Daniel Sims
Daniel Sims

Reputation: 531

Mock a protected method

I've looked through almost every link I can possibly find on google to do with this subject and have come up with two of the following solutions which do not run correctly. I have a protected method that simply returns a string.

protected virtual string ConfirmText
    {
        get
        {
            return "someTextHere";
        }
    }

This is in a viewmodel. My tests so far that I have tried are -

[TestMethod]
    public void Confirm_Text_test()
    {
        Mock<TestViewModel> testViewModel= new Mock<TestViewModel>(null, null, null);

        testViewModel.Protected()
            .Setup<string>("ConfirmText")
            .Returns("Ok")
            .Verifiable();


        testViewModel.Verify();
    }

I understand that with the above example I have only setup, and assert, not acted upon it. I haven't been able to find a way to act upon the set-up such as

var result = testViewModel.ConfirmText;

as it says it is inaccessible due to its protection level.

The next way I have tried is

var result = testViewModel.Object.GetType()
            .InvokeMember("ConfirmText",
             BindingFlags.InvokeMethod | 
             BindingFlags.NonPublic | 
             BindingFlags.Instance, 
             null, 
             testViewModel.Object, 
             null);

Am I missing something out, as most examples I've looked into show something similar to the first method I tried.

Upvotes: 4

Views: 1941

Answers (1)

Daniel Sims
Daniel Sims

Reputation: 531

As per the comment above posting this as an answer instead of an edit.

I solved this with the following advice from the above using reflection.

[TestMethod]
public void ConfirmText()
{
    TestViewModel testViewModel= new TestViewModel (null, null, null);

    var result = testViewModel.GetType()
    .InvokeMember("ConfirmText",
     BindingFlags.GetProperty |
     BindingFlags.NonPublic |
     BindingFlags.Instance,
     null,
     testViewModel,
     null);

    Assert.AreEqual("Confirm", result);
}

with the method being -

protected override string confirmText
{
    get
    {
        return Properties.Resources.confirmMessage;
    }
}

Upvotes: 2

Related Questions