Reputation: 1584
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
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