It's a little hard to tell what's going on without the whole test. The typical test pattern would be:
- create the fake
- configure the fake to set up the capturing of the argument
- execute the production code, which should use the fake, and
- then verify that a call was made.
I can't see where you call the
production code, but your A.CallTo
seems to be trying both to
configure the method and to verify that a call was made. Since you
said the MustHaveHappened
passes, I'm guessing that this code
lives after the call to the production code. Something like:
var repository = A.Fake<IRepository>();
repository.SaveSetup(…);
EmailEventArgs argsInEvent = null;
A.CallTo(repository).Where(w => w.Method.Name == "OnSaveRequest")
.Invokes(i => argsInEvent = i.GetArgument<EmailEventArgs>(0))
.MustHaveHappened(Repeated.Exactly.Once);
This will not work (of course you know that, or you wouldn't be asking a question) because you're configuring the Invokes
after the production code has been run (and the OnSaveRequest
call was already made on the fake).
You should have something like:
// Arrange
EmailEventArgs argsInEvent = null;
var repository = A.Fake<IRepository>();
A.CallTo(repository).Where(w => w.Method.Name == "OnSaveRequest")
.Invokes(i => argsInEvent = i.GetArgument<EmailEventArgs>(0));
// Act
repository.SaveSetup(…);
// Assert
A.CallTo(repository).Where(w => w.Method.Name == "OnSaveRequest")
.MustHaveHappened(Repeated.Exactly.Once);
// and maybe do something with argsInEvent