views:

163

answers:

2

Using RhinoMocks - can I fetch the parameters of a called function? I mean; can I get some of the unknown parameters from the function call out?

I have a mock, and I expect some function to be called on this. I know one of the parameters, but the other one is unknown as this comes from the class that uses the mock and calls a function on it. More specificly - in this case - the unknown argument is a lambda function. This is a callback function that is supposed to be called when the function is finished executing. As the mock prevents the callback from being called I want to fetch it and call it myself.

So; I want to check that the function was called. I want to make sure some of the arguments were the expected ones. And I want to get out the unknown arguments to do some operations on them afterwards.

Assuming both arguments are ints (for simplicity) I'd like to do something like this:

int unknownInt; 
_fakeSomething.AssertWasCalled(factory => factory.Foo(1, out unknownInt));
// then play around with unknownInt.. 

Can this be done? I see there is an Arg.Out, but couldn't quite make it work..

Note: Updated the question as it seemed to be misleading.

A: 

Not sure if it can be done, but testing like that can result in unreliable tests, as you don't know the actual paramter that was passed in.

If possible, test on explicit data. If you f.eks pass in null instead of a real value your test will likely pass for the wrong reason.

Testing with Arg.Is.Anything should be done carefully and when you truly don't care about the parameter, such as in AssertWasNotCalled.

Henning
I don't agree with you. To mention one example I have a service proxy that I Mock. I inject this service proxy when creating an object foo of some class that will use it. I then call a function on the object foo, and I expect this function to call a function on the service proxy mock with some arguments I expect, and also a callback function which is private to the class. Now I want to check that the function was called with the expected arguments, but I can't check for the private callback, and therefore specify Arg.Is.Anything. I don't care about that argument, so why shouldn't I?
stiank81
Ahh I see. I've had some trouble testing callbacks and lambdas as well. I came to the conclusion that my design was wrong.The beautiful thing about testing, and especially TDD is that it tells you when your design is wrong. Whether or not your design is wrong I cannot tell you, but if you find that your code is difficult to test maybe you should reconsider your design.
Henning
+3  A: 
Arg<string>.Matches(arg => you got the argument here...);

UPDATE:

To fetch the second argument made on the first call of the Foo method on _fakeSomething:

string someArg = null;
var args = _fakeSomething.GetArgumentsForCallsMadeOn(
    x => x.Foo(0, 0), 
    x => x.IgnoreArguments()
);
var int = (int)args[0][1];
Darin Dimitrov
Thanks. But from what I understood this is a plain match? Or can I use this to fetch the argument out? I want to fetch the argument out. My question might have been misleading, so I've updated my question text.
stiank81
Now it's clearer, see my update.
Darin Dimitrov
That's it! Thanks!
stiank81