views:

35

answers:

1

I have a class that inherits from an abstract base class. I am trying to verify that a specified protected method in the base class is called twice and I'd like to verify that the parameters passed are specific values (different for each call).

I was hoping that I'd be able to use Protected with either Expect or Verify, but seemingly I've missed what can be done with these methods.

Is what I'm attempting possible with moq?

UPDATE: An example of what I'm trying to do:

class MyBase
{
    protected void SomeMethodThatsAPainForUnitTesting(string var1, string var2)
    {
        //Stuf with file systems etc that's very hard to unit test
    }
}

class ClassIWantToTest : MyBase
{
    public void IWantToTestThisMethod()
    {
        var var1 = //some logic to build var 1
        var var2 = //some logic to build var 2
        SomeMethodThatsAPainForUnitTesting(var1, var);
    }
}

Essentially I want to test the way the variables var1 and var2 are created correctly and passed into SomeMethodThatsAPainForUnitTesting, so essentially I want to mock out the protected method, verify that it was called at least once and that the parameters were all passed correctly. If this was calling a method on an interface it would be trivial, but I'm coming unstuck with a protected method.

I can't easily change the design as it's brown field development and I'm not the only class calling the method.

+1  A: 

No it's isn't possible.

Tools like Moq and Rhino mocks work their magic by generating subclasses of the types you want to mock at run time. They generate all their "Verify" and "Expect" logic by overriding a member (in the case of virtual members) or implementing it (in the case of an interface) and inserting code to inspect or record the passed arguments and return the pre-canned response.

So what can you do to get around this? Firstly if you could alter the base method to be virtual this would then allow you to test your method by creating a test harness like so:-

class ClassIWantToTestHarness : ClassIWantToTest {
    public string Arg1 { get; set; }
    public string Arg2 { get; set; }
    public int CallCount { get; set; }

    protected override void SomeMethodThatsAPainForUnitTesting(var1, var2) {
        Arg1 = var1;
        Arg2 = var2;
            CallCount++;
    }
}

[Test]
public void ClassIWantToTest_DoesWhatItsSupposedToDo() {
    var harness = new ClassIWantToTestHarness();
    harness.IWantToTestThisMethod();
    Assert.AreEqual("Whatever", harness.Arg1);
    Assert.AreEqual("It should be", harness.Arg2);
    Assert.IsGreaterThan(0, harness.CallCount);
}

If it's not possible to alter the base class at all due to the code being so horribly brownfield you don't want to get your shoes dirty, you could simply wrap the method in ClassIWantToTest as a protected virtual method and perform the same trick on that instead. Moq does have support for overriding protected virtual members (see the miscellaneous section here) - though personally I prefer manual test harnesses in this case.

sighohwell