jmzagorski
jmzagorski

Reputation: 1155

FakeItEasy: Get Arguments from protected method returning null

I am trying to test the argument passed in a protected virtual method to make sure the properties were set correctly. However the statement below is not setting my variable, but FakeItEasy does recognize that this call is being made. Is my syntax incorrect?

Unit Test

EmailEventArgs argsInEvent = null;

A.CallTo(repository).Where(w => w.Method.Name == "OnSaveRequest")
    .Invokes(i => argsInEvent = i.GetArgument<EmailEventArgs>(0))
    .MustHaveHappened(Repeated.Exactly.Once);

Method in Repository

private void onSaveSetupEmailArgs(string callerName, int pk)
{
    EmailEventArgs args = new EmailEventArgs();

    // ..set property logic

    OnSaveRequest(args); // the protected virtual method
}

Upvotes: 1

Views: 1103

Answers (1)

Blair Conrad
Blair Conrad

Reputation: 241790

It's a little hard to tell what's going on without the whole test. The typical test pattern would be:

  1. create the fake
  2. configure the fake to set up the capturing of the argument
  3. execute the production code, which should use the fake, and
  4. 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

Upvotes: 4

Related Questions