Reputation: 185
I'm fairly new to UnitTesting and just encountered a situation I don't know how to handle and I'd appreciate any hints :)
The situation is as follows, imagine two methods:
// simple standalone method
public bool HelperMethod(string substr) {
return substr.Equals("abc");
}
// complex method making (multiple) use of HelperMethod
public bool ActualMethod(string str) {
for (var i=0; i<str.Length; i++) {
var substr = str.Substring(i, 3);
if (HelperMethod(substr))
return true;
}
return false;
}
HelperMethod functions without dependencies, ActualMethod however depends on HelperMethod and therefore its UnitTest will fail if HelperMethod's one does.
Actually, if I'm not mistaken, this is where mocking/dependency injection should come to rescue.
But in this specific case, I'd like to test several (arbitrary large) edge-cases (which may not be necessary for the code above, but the actual ActualMethod implementation is a part of fairly complex syntax parser). Since HelperMethod is called multiple times in each ActualMethod call, I would have to mock hundreds of HelperMethod calls for my test which just seems unbearable (now just imagine the number of needed HelperMethod calls would be quadratic to the input..).
My question is: how could one elegantly test a method that delegates a huge number of calls to another method? Should I really mock all these delegate calls? Or am I maybe allowed to make the method test depend on the other method's test (sth. like Assert(HelperMethodPassed)? Or is there no way around changing the design of the implementation?
Unfortunately inlining HelperMethod in the ActualMethod isn't possible because other methods rely on it as well.
Thanks in advance, I'd really appreciate any help! :)
PS: The project that is being tested is written in C# and I'm currently using the MSTest framework (but I'm open for switching to another framework if this solves the problematic).
Edit: explicitly marked HelperMethod and ActualMethod as public.
Upvotes: 5
Views: 740
Reputation: 58990
In general, if code is difficult to isolate for testing, it points to a design problem.
Since you're calling HelperMethod
a bunch of times in the context of the method you're trying to test, it sounds like the problem is that ActualMethod
is doing too much. You can make it more unit testable by breaking ActualMethod
down into smaller methods that take the output of HelperMethod
as a parameter, and then unit testing each of those individual methods.
Of course, you'll want to ensure that HelperMethod
is unit tested as well!
As other folks have stated, if the HelperMethod
is private and not used outside the class, then you can ignore the above advice and ensure that HelperMethod
is tested by making sure that you cover every reasonable permutation of test cases via the public interface (e.g. ActualMethod
). Fundamentally, though, if HelperMethod
contains complex logic, it should probably be unit tested independently.
Upvotes: 6
Reputation: 27085
What you can do is:
HelperMethod
so that all possible invocations from ActualMethod
are covered in the unit tests.HelperMethod
works and do not mock it, but use the actual implementation if you can guarantee that there aren't any side effects.If the tests for HelperMethod
fail, you can consider anything that ActualMethod
does as undefined behavior, so it is not relevant if these tests pass or fail.
Upvotes: 0
Reputation: 5664
If MethodHelper
is an implementation detail and is consequently a private method in the same class as ActualMethod
then I don't see a reason to test it seperately from ActualMethod
. You should be able to achieve full coverage by testing ActualMethod
.
Upvotes: 4