Optimax
Optimax

Reputation: 1584

Called method name inside FakeItEasy.Invokes()

FakeItEasy is amazing. A big "thank you" to all the contributors.

Having said that, I ran across a use case where I would like to know from inside the lambda configured with Invokes what method of the faked object was actually invoked, without having to explicitly configure Invokes for every method.

Here is a simple example of what I mean:

public interface ILogger {
    void Info(string msg);
    void Error(string msg);
}

var logger = A.Fake<ILogger>();

A.CallTo(logger).Invokes(
    () => {
        Debug.WriteLine(CurrentMethodName); 
        // CurrentMethodName should return "Error", or "Info", as appropriate
    });

logger.Error("Error");

Inside the lambda for Invokes, I would like to be able to tell what method on the interface was called. In other words, how do I implement CurrentMethodName?

This is what I tried:

public string CurrentMethodName
{
    get
    {
        StackTrace st = new StackTrace();
        StackFrame sf = st.GetFrame(1);
        return sf.GetMethod().Name;
    }
}   

The reason it doesn't work is that logger.Error is not in the call stack at all at this point. What is in the call stack is something like blah_blah_blah.AnonymousMethod__7_0() which is the anon. method supplied to the Invoke.

However, at the time CurrentMethodName is called FakeItEasy must be able to know what is being faked...

Is there a parameter, or global variable, or something I can access to see that indeed logger.Error was called?

Furthermore, can I list the values of arguments it was called with?

Upvotes: 3

Views: 2034

Answers (1)

Blair Conrad
Blair Conrad

Reputation: 241714

Glad you enjoy FakeItEasy.

There are several Invokes overloads. If you use one that takes an Action on the received call, you can achieve what you want:

A.CallTo(logger).Invokes(call =>
     Debug.WriteLine(call.Method.Name));

The call parameter knows a lot about the call, including the arguments passed in, accessible via call.Arguments or call.GetArgument.

Alternatively, you can get the arguments (up to 4 of them) directly by using an action that accepts the matching number of parameters:

 A.CallTo(logger).Invokes((string message) => Debug.WriteLine(message));

Upvotes: 5

Related Questions