Reputation: 25813
Suppose I have the following class:
public class TestBase
{
public bool runMethod1 { get; set; }
public void BaseMethod()
{
if (runMethod1)
ChildMethod1();
else
ChildMethod2();
}
protected abstract void ChildMethod1();
protected abstract void ChildMethod2();
}
I also have the class
public class ChildTest : TestBase
{
protected override void ChildMethod1()
{
//do something
}
protected override void ChildMethod2()
{
//do something completely different
}
}
I'm using Moq, and I'd like to write a test that verifies ChildMethod1() is being called when I call BaseMethod() and runMethod1 is true. Is it possible to create an implemention of TestBase with Moq, call BaseMethod() and verify that ChildMethod was called on the Moq implementation?
[Test]
public BaseMethod_should_call_correct_child_method()
{
TestBase testBase;
//todo: get a mock of TestBase into testBase variable
testBase.runMethod1 = true;
testBase.BaseMethod();
//todo: verify that ChildMethod1() was called
}
Upvotes: 3
Views: 6257
Reputation: 1871
You can also set the expectation/setup as Verifiable and do without a strict mock:
//expect that ChildMethod1() will be called once. (it's protected)
testBaseMock.Protected().Expect("ChildMethod1")
.AtMostOnce()
.Verifiable();
...
//make sure the method was called
testBase.Verify();
Edit This syntax does not work in current versions of Moq. See this question for how to do it as of at least 4.0.10827
Upvotes: 5
Reputation: 25813
I figured out how to do this. You can can mock protected methods with Moq, and by making a strict mock, you can verify that they were called. Now I can test the base class without having to make any subclasses.
[Test]
public BaseMethod_should_call_correct_child_method()
{
//strict mocks will make sure all expectations are met
var testBaseMock = new Mock<TestBase>(MockBehavior.Strict);
//expect that ChildMethod1() will be called once. (it's protected)
testBaseMock.Protected().Expect("ChildMethod1")
.AtMostOnce();
var testBase = testBaseMock.Object;
testBase.runMethod1 = true;
testBase.BaseMethod();
//make sure the method was called
testBase.VerifyAll();
}
Upvotes: 4
Reputation: 19879
It's a bit of a hack, but how about creating a subclass of TestBase that makes ChildMethod1 and ChildMethod public and then Moqing that?
Upvotes: 1
Reputation: 1028
It seems like your testing the behaviour rather than the public interface. If this is intended then you could probably look at advice for testing private members.
"Is it possible to create an implemention of TestBase with Moq, call BaseMethod() and verify that ChildMethod was called on the Moq implementation?"
It's sort of possible. But then you would be testing the mock object, not the real object.
Two questions that might steer you in the right direction:
Does the descendatn class return a different value than the base class? If so you can test for that and ignore implimentation details (makes refactoring alot easier too).
Does the descendant class call different methods or different dependencies? If so you can check the dependencies.
Upvotes: 0