Reputation: 15282
Basically, I have a method on my class that invokes an Action<T>
if certain conditions are met. How can I unit test to ensure that the action is invoked?
public class MyClass<T>
{
private IDBService _dbService;
private Action<T> _action;
public MyClass(IDBService dbService, Action<T> action)
{
if (dbService == null) throw new ArgumentNullException("dbService");
if (action == null) throw new ArgumentNullException("action");
_dbService = dbService;
_action = action;
}
public void CallActionIfPossible(T param)
{
if (_dbService.IsTopUser)
action(param);
}
}
Upvotes: 3
Views: 7048
Reputation: 29776
Jason's answer is good, but one caveat that is often overlooked is that you will often need to test for a certain number of invocations (e.g. not only was it called, but it was called exactly once). So I often do something like this:
var callCount = 0;
Action<Foo> action = _ => callCount++;
Bar<Foo> bar = new Bar<Foo>();
// set up conditions that should guarantee action is invoked
bar.M(action);
Assert.That(callCount, Is.EqualTo(1));
Upvotes: 5
Reputation: 241591
Well, the basic idea is that the Action<T>
produces some state change somewhere (if it doesn't, what's the point?). So, unit test that the expected state change occurs when the conditions hold, and that the expected state change doesn't occur when the conditions do not hold.
Of course, ideally, you mock the Action<T>
so that the state testing is super easy. You do not need Moq or any other mocking framework for this:
bool actionWasInvoked = false;
Action<Foo> action = foo => actionWasInvoked = true;
Bar<Foo> bar = new Bar<Foo>();
// set up conditions that should guarantee action is invoked
bar.M(action);
Assert.IsTrue(actionWasInvoked);
and
bool actionWasInvoked = false;
Action<Foo> action = foo => actionWasInvoked = true;
Bar<Foo> bar = new Bar<Foo>();
// set up conditions that should guarantee action is NOT invoked
bar.M(action);
Assert.IsFalse(actionWasInvoked);
Of course, I don't know your exact setup. Maybe you pass in action
on construction of Bar
, or maybe you have some other way of setting the action. But the idea should be clear.
Upvotes: 10