I want to test the following logic (this is obviously a stripped-down version of my method):
public void myPublicMethod(params) {
if(some_condition)
privateMethod1();
else
privateMethod2();
}
I have all of the other dependencies in the method mocked out, and I've set this up so that I can guarantee that some_condition is true. What I want to do is verify that my privateMethod1() is called exactly once, and privateMethod2() is not called at all. Is this possible to do with Moq?
Here are some notes on the issue:
Any thoughts? Thanks in advance. I'm willing to accept that this can't be done, but I'd like to know one way or another.
Don't test private methods. They are private implementation details of the class. You should only test the results of executing public methods. As long as your results come out as expected, you shouldn't care how the result is obtained.
Building tests on private methods will lead to brittle tests that break easily when you refactor private implementations (for performance or other reasons).
Your class has two private utility methods that encapsulate some useful behavior, and the public method that you are testing must make use of this behavior. However, when you test, you don't want the normal behavior from these methods, you want to substitute a test behavior. What you have here is a classic case of dependency. When testing, dependecies within the class can be problematic.
So the solution is the same as for an external dependency: use dependency injection of one kind or another to delink the method you want to test from the private methods that implement the behavior. For instance, two private delegates can be declared to represent the behavior:
private Action Behavior1;
private Action Behavior2;
In the class constructor, the normal behavor is implemented thus:
public Foo (...)
{
Behavior1 = privateMethod1;
Behavior2 = privateMethod2;
...
}
In the public method the delegate is called instead of the actual method:
public void myPublicMethod(params) {
if(some_condition)
Behavior1();
else
Behavior2();
}
By doing this the absolute dependency among the methods has been eliminated, so now it is testable.
So now, in the test, after the test object instance has been created, you can override the dependent behavior:
Foo_Accessor testMe = new Foo_Accessor();
bool wasCalled1 = false
testMe.Behavior1 = new Action(() => wasCalled1 = true);
...
Assert.IsTrue(wasCalled1);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With