How does the .Returns<T> (this T value, ... ) extension method work under the hood?
Specifically, how does .Returns know what method it is intended to configure just from the result of executing that method?
Example:
public interface ICalculator { Add(int a, int b); }
// create mock
var calculator = Substitute.For<ICalculator>();
// How does this piece work under the hood?
calculator.Add(1, 2).Returns(3);
Whenever a substitute receives a call, it records information about the call, and updates some global state (threadlocal, as Scott pointed out) recording that it was the most recent substitute called.
When .Returns runs, it looks up the last substitute called, then tells the substitute that its last call should be stubbed to return that specific value. (It also removes it from the collection of received calls, so if we run .Received() the stubbed call doesn't get confused for a real one.)
calculator
.Add(1, 2) // substitute records Add(1,2) called. Last substitute
// set to `calculator`. Returns default `int` in this case.
.Returns(3) // Looks up last sub, sets its last call to return 3.
I think this is a reasonable approximation of what happens. To add a little more precision in case you want to look at the code, a substitute is a dynamic proxy which forwards every call to a "call router" which handles all the logic of the substitute (storing calls, configuring calls, adding callbacks etc.). The global state is a SubstitutionContext, which stores the last call router that received a call.
(Repo links are to v4.0.0-rc1 tag. Later versions may change, but the overall idea should remain fairly consistent.)
I believe that it works by saving a context (called ISubstitutionContext) in thread local storage when a mocked method is called. Then the call to Returns grabs this context and sets appropriate data in the return object.
The actual implementation of the mocked method would (extremely crudely) look something like:
//Dynamically created mock
public int Add(int a, int b)
{
var context = new SubstitutionContext("Add", ...);
//CallContext.LogicalSetData or
//ThreadStatic or
//ThreadLocal<T> or
//...
return 0;
}
//In some extension class
public static ConfiguredCall Returns<T>(this T value, ...)
{
var context = SubstitutionContext.Current; //Gets from thread local storage
return context.LastCallShouldReturn(value);
}
Related
Please see the code below:
mockBusinessLayer.Setup(m => m.Calculate(It.IsAny<integer>(), It.IsAny<integer>())).Callback
(() => mockBusinessLayer.SetupGet(y => y.FirstNumber).Returns(Helper.FirstNumber));
mockBusinessLayer.Setup(m => m.Calculate(It.IsAny<integer>(), It.IsAny<integer>())).Callback
(() => mockBusinessLayer.SetupGet(y => y.SecondNumber).Returns(Helper.SecondNumber));
Calculate() accepts two integers and adds them together. How do I setup multiple SetupGets on the same mock object? The above code only sets up the Get callback on SecondNumber (because it is the last time SetupGet is called).
Update
This is the function I am trying to test:
public CalculatorDTO Calculate(int NumberOne, int NumberTwo)
{
_Calculator.Calculate(NumberOne, NumberTwo);
return Mapper.Map<CalculatorDTO>(_changeCalculator);
}
}
Is it better to do this:
mockBusinessLayer.Setup(x => x.FirstNumber).Returns(Helper.FirstNumber);
mockBusinessLayer.Setup(x => x.SecondNumber).Returns(Helper.SecondNumber);
You say:
The above code only sets up the Get callback on SecondNumber (because it is the last time SetupGet is called).
But that's not quite right: your calls to Setup of Calculate are identical and thus the second one overrides the first. It's as if the first Setup never occurred.
Putting the calls to SetupGet in the Callback is unnecessary and confusing. I'd set it up like this:
mockBusinessLayer.SetupGet(y => y.FirstNumber).Returns(Helper.FirstNumber)
mockBusinessLayer.SetupGet(y => y.SecondNumber).Returns(Helper.SecondNumber)
mockBusinessLayer.Setup(m => m.Calculate(It.IsAny<integer>(), It.IsAny<integer>()));
Any time FirstNumber is gotten, it will return Helper.FirstNumber, and likewise for SecondNumber returning Helper.SecondNumber.
All that being said, without more of your code (What type is _Calculator? Does your mockBusinessLayer really expose FirstNumber/SecondNumber and Calculate?) it's hard to offer more complete steps to move forward. For instance, you don't show the setup of your Mapper.Map method, which you'll need if you want to test this method.
In response to your update...
SetupGet offers a slightly cleaner API: you're required to pass a Func, while Setup will allow you to pass an Action; it returns a slightly more restricted ISetupGet interface. SetupGet also has better semantics, indicating to readers that you intend to set up only the get.
In the Moq source they actually boil down to the same code so either get the job done just as well.
Given the following simple service class, in the GetCategories() method, should you test the fact that the categoryRepository.Query() method was called, or should you be setting up a test that keeps a list of categories and returns those?
I guess what I am saying is would mocking the categoryRepository and verifying that it's Query method was called once cover this test case?
public class CategoryService : ValidatingServiceBase, ICategoryService
{
private readonly IRepository<Category> categoryRepository;
private readonly IRepository<SubCategory> subCategoryRepository;
private readonly IValidationService validationService;
public CategoryService(
IRepository<Category> categoryRepository,
IRepository<SubCategory> subCategoryRepository,
IValidationService validationService)
: base(validationService)
{
this.categoryRepository = categoryRepository;
this.subCategoryRepository = subCategoryRepository;
this.validationService = validationService;
}
public IEnumerable<Category> GetCategories()
{
return categoryRepository.Query().ToList();
}
}
Sample Test
[Fact]
public void GetCategories_Should_CallRepositoryQuery()
{
var categoryRepo = new Mock<IRepository<Category>>();
var service = new CategoryService(categoryRepo.Object, null, null);
service.GetCategories();
categoryRepo.Verify(x => x.Query(), Times.Once());
}
It doesn't matter. In both cases (mock + behavior verification vs stub + assertion) you achieve exactly the same result and require exactly the same level of details about inner workings of class. Stick to whichever one you think is more suited in given scenario.
Unit test you posted is an example of behavior verification. You don't assert any values but instead check whether some method was called. This is especially useful when method call has no visible results (think about logging) or doesn't return any value (obviously). It of course has drawbacks, especially when you do such verification for methods that do return value, and don't check it (as is your case - we'll get to it).
The stubbing and asserting approach uses the collaborators to generate value. It doesn't check whether methods were called (at least not directly, yet such test is performed when you setup stub and that setup works), but instead relies on correct flow of stubbed value.
Let's go with simple example. Say you test a method of your class, PizzaFactory.GetPizza which looks like this:
public Pizza GetPizza()
{
var dough = doughFactory.GetDough();
var cheese = ingredientsFactory.GetCheese();
var pizza = oven.Bake(dough, cheese);
return pizza;
}
With behavior verification you'd check whether doughFactory.GetDough was called, then ingredientsFactory.GetCheese and finally oven.Bake. Had such calls indeed been made, you'd assume pizza was created. You don't check that your factory returns pizza, but assume it happens if all process' steps were completed. You can already see that drawback I mentioned earlier - I can call all the correct methods but return something else, say:
var dough = doughFactory.GetDough();
var cheese = ingredientsFactory.GetCheese();
var pizza = oven.Bake(dough, cheese);
return garbageBin.FindPizza();
Not the pizza you ordered? Notice that all the correct calls to collaborators happened just as we assumed they would.
With stub + assert approach it all looks similar except instead of verification you have stubbing. You use values generated by earlier collaborators to stub later collaborators (if somehow you get wrong dough or cheese, oven will not return pizza we wanted). The final value is what your method returns and this is what we assert:
doughFactoryStub.Setup(df => dg.GetDough).Return("thick");
ingredientsFactoryStub.Setup(if => if.GetCheese()).Return("double");
var expectedPizza = new Pizza { Name = "Margherita" };
ovenStub.Setup(o => o.Bake("thick", "double")).Return(expectedPizza);
var actualPizza = pizzaFactory.GetPizza();
Assert.That(actualPizza, Is.EqualTo(expectedPizza));
If any part of the process fails (say doughFactory returns normal dough) then the final value will be different and test will fail.
And once again, in my opinion in your example it doesn't matter which approach you use. In any normal environment both methods will verify the same thing and require same level of knowledge about your implementation. To be extra safe you might want to prefer to use the stub + assert approach in case somebody plants you a garbage bin1. But if such thing happens, unit tests are your last problem.
1 Note however that it might not be intentional (especially when complex methods are considered).
Yes, that would be the way.
mockCategoryRepository.Setup(r => r.Query()).Returns(categories)
var actualCategories = new CategoryService(mockCategoryRepository, mock..).GetCategories();
CollectionAssert.AreEquivalent(categories, actualCategories.ToList());
It would look something similar with Moq and NUnit.
What you've presented is a white-box test - an approach also possible in unit testing, but recommended only for simple methods.
In the answer presented by Sruti the service is tested in a black-box sense. The knowledge about the inner method is used only to prepare the test, but you don't verify if the method was called one time, 10 times, or wasn't called at all. Personally, I verify method calls only to verify that some external API that must be stubbed is used correctly (example: sending e-mails). Usually it is sufficient not to care about how a method works, as long as it's producing correct results.
With black-box tests the code and the tests are easier to maintain. With white-box tests, most changes of some internal structure during refactoring of a class usually must be followed by changing test code. In black-box approach you have more freedom to rearrange everything, and still be sure that interface's external behaviour hasn't changed.
I have been trying to get past this problem for a couple of days now to no avail. I am trying to test the functionality of AnObject.AnAction (preemptive apologies, I have to obfuscate class/method names.) My goal is to keep MyTestObj.do_work(AnObject) from actually doing anything when it is called. It has code that I do want to be called in a unit test environment.
Here is my Unit test code:
Mock< MyTestObj > myTestObj_mock = new Mock< MyTestObj > ();
myTestObj_mock.Setup( e => e.do_work( It.IsAny< AnObject > () ) );
...
AnObject tester = new AnObject();
tester.anAction( myTestObj_mock.Object );
within the method AnObject.AnAction( MyTestObj mto ):
...
mto.do_work( this );
...
It is at this point when ran that I get this error:
System.InvalidCastException : Unable to cast object of type
'myNamespace.AnObject' to type 'System.Delegate'.
MyTestObj.do_work is a virtual method.
I have absolutely no idea why this error is coming up. I've stepped through the code as NUnit ran it and I am certain that is the point in which it crashes. It will not go any further into the code.
I'm really stumped. Does anybody have any idea what is going on?
Thanks in advance!
***Updates***
I tried to create an instance of AnObject within AnObject.AnAction and pass it instead of 'this':
...
AnObject test = new AnObject();
mto.do_work( test );
...
This did not have any effect.
As your question is written you do not need to setup the myTestObj_mock.do_work().
Setup is used to say, when method X is called return value Y. Or alternativly that when method X is called, exception Z is returned. Ask yourself is that really what I need to do?
Here you aren't returning anything from the method:
mto.do_work( this );
Also, here:
myTestObj_mock.Setup( e => e.do_work( It.IsAny< AnObject > () ) );
You aren't defining any Return for your setup.
You should be able to supply a mock myTestObj_mock without defining the setup in this case. Just remove the line with the Setup and run the test again.
A guess:
If you defined the Setup because you wanted your test to make sure AnObject.AnAction really calls the do_work method, what you need to do is define a Verify method rather than a Setup, likewise:
mock.Verify(foo => foo.Execute("ping"));
or in your case something like
myTestObj_mock.Verify(m => m.do_work(It.IsAny< AnObject > ()), Times.AtLeastOnce());
Another guess:
If you defined the mock because you pass a "this" reference and expect do_work to modify some parameters of "this" for the test to pass then you shouldn't be mocking here. Remember that mocks aren't really instances of your objects, so the code that modify the this reference will never get called.
I was finally able to get to a compiler and play with the code and here is what I found. It is basically what Giles said above for his first part of the question.
Here is the code hint for Setup:
Specifies a setup on the mocked type for a call to a value returning method.
And, here is the actual code for Setup
public ISetup<T> Setup(Expression<Action<T>> expression)
So, Setup is actually setting up the code as an Action (a delegate, basically). When the test runner is run, it hits this point and usually expects to feed the delegate to the Returns method
public IReturnsResult<TMock> Returns(TResult value)
So, this is never done, and instead of Mock running through the whole expected path and negotiating all of the code out, then it returns mistyped values.
Sooo, this is basically where Giles explanation is correct. If you are testing that the do_work method is being called, then you want to use Verify (which truly uses your fake object as a mock). However, if not, then you have no need to even set this up as it does nothing. If that is the case, then maybe that piece of code should not be in that specific code block, but you would be best to evaluate that.
And, finally, the Setup method should only be used if you are truly using your object as a stub, simply using it to inject logic into your code.
Hopefully, that makes sense and helps you with your problem.
Also, a Callback might be of use here depending on what you are doing. But, I am not sure. They have many examples in the Moq quickstart
UPDATE FOR MY ATTEMPT AT RECREATING using Version 4.0.10827...and had no issues
[Test]
public void teststuff()
{
Mock<MyTestObj> myTestObj_mock = new Mock<MyTestObj>();
myTestObj_mock.Setup(e => e.do_work(It.IsAny<AnObject>()));
AnObject tester = new AnObject();
tester.anAction(myTestObj_mock.Object);
}
...
public class MyTestObj
{
public virtual void do_work(AnObject o)
{
}
}
public class AnObject
{
public void anAction(MyTestObj obj)
{
obj.do_work(new AnObject());
}
}
I have a method called SubmitRequest wich takes a request object. It fills in some additional values like the sequence id the DB generates and submitted date. Then returns the same object. Is it better to just leave it as a VOID method?
Request request = JsonConvert.DeserializeObject<Request >(jsonFormData);
RequestManager frMan = new RequestManager();
//frMan.SubmitRequest updates the request object by updating some of its properties.
request = frMan.SubmitRequest(request);
return request;
A void would still work as the request would be modified:
frMan.SubmitRequest(request);
but are there any advantages or disadvantages of these two ways?
There's no harm in writing it that way. In fact, it's the basis of a fluent interface.
I would say the important thing here is not to make your code confusing.
I would either return the same object...
public Request SubmitRequest(Request request)
or use a ref parameter to indicate your intentions...
public void SubmitRequest(ref Request request)
or I guess you could just document your method fully so it is clear and do...
/// <summary>
/// This function will modify your request data!
/// </summary>
/// <param name="request">The request data to be submitted</param>
public void SubmitRequest(Request request)
The assignment back into request suggests that SubmitRequest can return something different, say, it returns a new request that is somehow related to the submitted one.
Typically, the case where you see this "return the object back" pattern is a return this to permit method chaining.
var result = request.SubmitTo(frMan).WaitForResult().GetResult();
IMO, you need to think about what's happening here.
Just looking at the code, I would assume that this is what's happening:
1) frMan submits the passed in request
2) frMan returns a new request
Which is not the steps that you've described in the text of the question.
Since you're manipulating the Request object, and then (presumably doing something with it later) I would have the request object be passed to the method BY REFERENCE and return void. That way I know that I'm only dealing with one Request object, and that it's the same one. Additionally, I would provide "SubmitRequest" with a more logically defined name that describes what you're doing to the request object.
I think that's fine as part of something like the builder pattern (see StringBuilder.Append for example). However:
It's not really clear to me that in this case it's a good idea.
You should explicitly document that this is exactly how the method behaves, and that it will never return a different reference.
If you don't need to do anything with the modified object then I wouldn't return it in the method call.
Thinking about this in the Command/Query paradigm, SubmitRequest looks more like a command than a query in which case it makese sense not to return a value.
It is better to leave it as a void method.
The idea of returning an object is so when something changes, but if nothing changes at all. Then data isn't being manipulated so theres no point of using a return
ex:
Object bar = new Object();
// this doesn't do anything. (it wont change the local scope of the object value)
foo(bar); // can be same as void.
//changes the value, but the method returns the same object... whats the point?
bar = foo(bar);
public Object foo(object bar)
{
return bar;
}
Although theoretically, it won't do any harm.
The caller of the method has no guarantee that the instance you return is the same one they provide. When you return void, you are explicitly stating that the caller can be sure they are dealing with the same instance after the call completes.
In returning an object, in the following manner:
private SomeObject DoSomeStuff(SomeObject item)
{
// perform work on item and change values
return item;
}
instead of
private SomeObject DoSomeStuff( ref SomeObject item)
{
//perform work on item
}
As I understand it you'll incur a slight performance hit as a new object of type SomeObject will be created and returned, leaving the garbage collector to tidy up the original object.
As already pointed out if you were to perform any instance checking then this would also fail.
If the point of
frMan.SubmitRequest(request);
is to update the Request argument, then shouldn't this be a property of the Request object not the RequesManager? Something like
request.Submit();
?
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.
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];
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.