Reputation: 4116
I am trying to unit test a method which has a line
_pollingService.StartPolling(1000, PollingHit)
Where PollingHit is a private method in calling class and signature of StartPolling is
public void StartPolling(double interval, Action action)
now whatever is inside PollingHit(), how do I test that ? Since responsibility of calling this method is on PollingService, but since that is not a class under test I should not be creating a concrete object of it.
Upvotes: 1
Views: 1433
Reputation: 32964
Test it though the public methods of the class which contains _pollingService
based on the desired behaviour of that class. you can test polling service itself by just checking that it calls the passed action, it doesn't matter what that action is.
When you test polling service you should only test that when you start polling it calls the given action at the given interval. Polling service doesn't know anything about PollingHit
method (as it is in a different class). To test this you could pass pollingservice
a test method which implements a counter and check that the counter is incremented as you would expect. You can (and should) test this without the PollingHit
method.
When you come to test the behaviour of the class that is using pollingService
, you want to test its behaviour, regardless of how it is implemented. The fact that it uses polling service to call the PollingHit
method is an irrelevant implementation detail, what is important is that the behaviour encapsulated by the PollingHit
method is invoked when you need it to be.
Imagine if someone comes up with an 'push' based way of doing what you you are currently doing by polling (which is a 'pull' model) and implements a pushNotificationService
. The behaviour of the class which uses the polling service should remain the same even after you have refactored it to remove pollingService
and replaced it with the new pushNotificationService
. If you test the behaviour only then your tests won't need to change after you have made this refactoring change.
If you are already using a mock PollingService
then you can probably ditch that and use your own test double and use this to control the invocation yourself. Something like this:
public class TestPollingService : IPollingService
{
Action theAction;
public void StartPolling(double interval, Action action)
{
theAction = action;
}
public void TestInvocation()
{
theAction();
}
}
Upvotes: 1