I am new to mocking. I need to mock method (it doesn't have return value). I cannot find any examples of how to mock a method. I need to mock ITempDa.Import method.
var stub = MockRepository.GenerateStub<ITempDA>();
stub.Stub(x => x.Import(param1)). ???
public void MockedImport() {
// some processing here
}
ITempDa.Import should be mocked and instead some internal method "MockedImport" should be called.
As #JamesLucas said you don't need to use Return() method(you should use this method only when your method is not void).
In this case you should use the Do() method:
var stub = MockRepository.GenerateStub<ITempDA>();
stub.Stub(x => x.Import(Arg<object>.Is.Anything))
.Do(new Action<object>(o => MockedImport()));
or if MockedImport ths same arguments as Import:
stub.Stub(x => x.Import(Arg<object>.Is.Anything))
.Do(new Action<object>(MockedImport);
You should use WhenCalled method when the method under test called your fake and you want to intercept the execution(execute something + change return value/change arguments/do additional steps and etc...). Another reason to use Do instead of WhenCalled is, your code become more readable.
Usually I do not recommend to use IgnoreArguments method. The reason is quite simple, you test the method behaviour. When something violate the method behaviour then the test should fail. IgnoreArguments easily hide things. However, if the calling parameters aren't important do:
stub.Stub(x => x.Import(null))
.IgnoreArguments()
.Do(new Action<object>(o => MockedImport()));
In this instance you don't need a Return() call as the method is void returning. If you want to intercept the call and perform some logic on the mocked operation then use WhenCalled. In this scenario it's also worht just ignoring the arguments in the Stub and handling everything in the WhenCalled expression. e.g.
var stub = MockRepository.GenerateStub<ITempDA>();
stub.Stub(x => x.Import(null))
.IgnoreArguments()
.WhenCalled(invocation =>
{
var arg = invocation.Arguments[0] as ...;
// etc
});
Related
I'm reading a book on unit testing which says
Asserting interactions with stubs is a common anti-pattern that leads to fragile tests.
Below is an example:
[Fact]
public void Creating_a_report() {
var stub = new Mock<IDatabase>();
stub.Setup(x => x.GetNumberOfUsers()).Returns(10);
var sut = new Controller(stub.Object);
Report report = sut.CreateReport();
Assert.Equal(10, report.NumberOfUsers);
stub.Verify(x => x.GetNumberOfUsers(), Times.Once); // <--- Asserts the interaction with the stub, which is not correct
}
I don't quite get it. Let's say if you refactor the code base and change the name/method signature of GetNumberOfUsers method, even though you don't have stub.Verify(x => x.GetNumberOfUsers(), Times.Once);, you still need to modify the code stub.Setup(x => x.GetNumberOfUsers()).Returns(10); to make the test code compile or pass. Whith stub.Verify(x => x.GetNumberOfUsers(), Times.Once); I can at least make sure the code logic is correct (GetNumberOfUsers method will be called, if it doesn't, then there is a serious bug in it, so it is like extra protection)
Dear RhinoMocks users out there. I am a newbie to RhinoMocks and have a problem wrapping my head around something. I need to test two methods in a class, on of them calls the other multiple times. I already tested the one called multiple times separately, the setup is somewhat complex so the idea for testing the other method was to stub the method that has been tested already. Here is a minimal example:
public class TestedClass
{
public virtual void DoSthOnce(List<int> listParam)
{
foreach (var param in listParam)
DoSthMultipleTimes(param);
}
public virtual void DoSthMultipleTimes(int intParam)
{
Console.WriteLine("param: " + intParam);
}
}
I.e. DoSthMultipleTimes() is already tested. The following test code works and verifies that the DoSthMultipletimes()-Method was called for each element of the list that was provided as parameter to DoSthOnce().
var paramList = Enumerable.Range(1, 10).ToList();
var mock = MockRepository.GeneratePartialMock<TestedClass>();
mock.Stub(m => m.DoSthMultipleTimes(Arg<int>.Is.Anything))
.WhenCalled(mi =>
{
// Only for debug; this method is empty in the actual test code.
Console.WriteLine("Stub called with " + mi.Arguments[0]);
});
mock.DoSthOnce(paramList);
// This will not throw an exception
foreach (var param in paramList)
mock.AssertWasCalled(m => m.DoSthMultipleTimes(param));
The output is as expected:
Stub called with 1
Stub called with 2
Stub called with 3
Stub called with 4
Stub called with 5
Stub called with 6
Stub called with 7
Stub called with 8
Stub called with 9
Stub called with 10
However, the following fails throwing an exception although it should be the same thing as above, at least from my understanding:
var paramList = Enumerable.Range(1, 10).ToList();
var mock = MockRepository.GeneratePartialMock<TestedClass>();
mock.Stub(/*same as above*/).WhenCalled(/*same as above*/);
foreach (var param in paramList)
mock.Expect(m => m.DoSthMultipleTimes(param));
mock.DoSthOnce(paramList);
mock.VerifyAllExpectations();
The console output is identical, but an ExpectationViolationException is thrown by VerifyAllExpectations(). Additional information is:
TestedClass.DoSthMultipleTimes(1); Expected #1, Actual #0.
TestedClass.DoSthMultipleTimes(2); Expected #1, Actual #0.
...
TestedClass.DoSthMultipleTimes(10); Expected #1, Actual #0.
The parameters are correct, but what exactly is the problem here?
I'm guessing because of your stub itself.
This piece of code would register the various expectations that you want:
foreach (var param in paramList)
mock.Expect(m => m.DoSthMultipleTimes(param));
This would set the Expectation that DoSthMultipleTimes(1), DoSthMultipleTimes(2), etc are being called.
However your Mock.Stub code would override / stubbing the implementation itself. This resulted that Rhino would execute this override/method (and not calling the original DoSthMultipleTimes method of the original class). As such, when VerifyAllExpectation being called, none of the method in original class was called.
You could verify the above by removing the following:
mock.Stub(m => m.DoSthMultipleTimes(Arg<int>.Is.Anything))
.WhenCalled(mi =>
{
// Only for debug; this method is empty in the actual test code.
Console.WriteLine("Stub called with " + mi.Arguments[0]);
});
Since you are using PartialMock, if you are not implementing the stub, it would call the original method. And supposedly, it would now successfully pass all the expectation.
(NB: beware when using PartialMock as it would run the original method if not being stubbed (ie: database call, etc)).
It is possible to test if a method has been called using Moq and dependency injection. However, is it possible to test if one method in a class calls another within the same class?
For example, I want to test that if I log a certain exception, that an information message is logged as well.
The method is:
public void Error(string message, Exception exception, long logId = 0)
{
var int32 = (int)logId;
Info("Id was converted to an int so that it would fit in the log: " + logId, int32);
Error(message, exception, int32);
}
This was my attempt at unit testing it. The test fails, is there any way that it can it be done?
void logging_an_error_with_a_long_id_also_logs_info()
{
var mock = new Mock<ILogger>();
var testedClass = new Logger();
var counter = 0;
testedClass.Error("test" + counter++, new Exception("test" + counter), Int64.MaxValue);
mock.Verify(m => m.Info(It.IsAny<string>(), It.IsAny<int>()));
}
Since the Info and Error methods are in the same class (ClassA), I don't believe I can pass ClassA as a dependency into ClassA. So does it not need tested?
The best you're going to be able to do is to make Info virtual. This will allow you to create a Mock<Logger>, set CallBase = true, and verify that Info was called.
var mock = new Mock<Logger>
{
CallBase = true
};
mock.Object.Error("test" + counter++, new Exception("test" + counter), Int64.MaxValue);
mock.Verify(m => m.Info(It.IsAny<string>(), It.IsAny<int>()));
This way, you're still calling the actual implementation of Error, but you've used Moq to verify the Info method was called.
It feels like you're trying to test the wrong thing. It's not really important that the Info method on your class is called from the Error method, what's important is that the behaviour of the Info method occurs. How it happens is an implementation detail of the class.
If I had a math class with two functions:
public int Mult(int x, int y) {
return x*y;
}
public int Sqr(int x) {
return Mult(x,y);
}
I wouldn't test that calling Sqr called out to the Mult function, I would test Sqr(4)==16. It doesn't matter if that calculation takes place in the Sqr method, or in another method of the class.
Whilst #Andrew's solution is probably what you're after, mocking the class you're testing tends to lead to tightly coupled, brittle tests.
If it's impractical to test the call by observing it's side effects, then it may be a sign that the implementation could use a bit of refactoring.
I'm trying to create some unit tests for an application I've recently inherited. Currently using NSubstitute because that's what the previous programmer used, but I'm not attached to it.
The method I'm testing calls the DataService class' Create method.
Calling Create Method
var contactProductLink = this.dsService.Create<ContactProductLink>(x =>
{
x.ContactRoleId = prod.RoleId;
x.ContactId = contactViewModel.ContactId;
x.ProductId = prod.ProductId;
x.Active = true;
x.InsertDate = DateTime.Now;
x.InsertUserId = user.employeeId;
x.UpdateDate = DateTime.Now;
x.UpdateUserId = user.employeeId;
});
DataService Create Method:
public TEntity Create<TEntity>(Action<TEntity> propertySetter = null) where TEntity : class
{
var tEntity = this.Context.Create<TEntity>();
if (propertySetter != null)
{
propertySetter(tEntity);
}
return tEntity;
}
The approach I've taken (and maybe there's a better way) is to use NSubstitute to mock the DataService. When I'm doing my assertions at the end, I'm checking to make sure that the Create method was called:
mockDataSupplierService.Received().Create<ContactProductLink>(Arg.Any<Action<ContactProductLink>>());
However, I'd like to also verify the input that was sent to the method is correct, and here's where I'm running into trouble. I can get the System.Action object that was passed to the Create method, but I can't figure out how to pull out the parameters (such as ContactRoleId, ContactId, etc. as posted in the calling create method code snippet).
So after all of that what I'm asking is:
How can I access those input parameters so I can verify the correct arguments are being passed to the data service? Is it even possible?
Is there a better way to do this than what I'm currently trying to do?
Solution
//Arrange
mockDataSupplierService.Create<ContactProductLink>(Arg.Do<Action<ContactProductLink>>(x=> actionToPopulateEntity = x));
//Assert
mockDataSupplierService.Received().Create<ContactProductLink>(Arg.Any<Action<ContactProductLink>>());
var entity = new ContactProductLink();
actionToPopulateEntity.Invoke(entity);
Assert.AreEqual(ExpectedContactId, entity.ContactId);
How can I access those input parameters so I can verify the correct arguments are being passed to the data service? Is it even possible?
Essentially you can't, as it is not possible to extract "code" details from action (consider what happens when you pass an action that doesn't set any properties - this is totally legal, but would break hypothetical mechanism).
However, you can try this instead:
Create entity with initial values
Use Arg.Invoke argument, telling NSubstitute to use chosen object as action parameter
Verify that entity properties values changed
For example:
// Arrange
var entity = new ContactProductLink
{
ContactRoleId = // ...
// ...
};
mockDataSupplierService
.Create<ContactProductLink>(Arg<ContactProductLink>.Invoke(entity));
// Act
// ...
Assert.That(entity.ContactRoleId, Is.EqualTo(2));
// ...
Oook,
I'm wanting to mock a callback that I know my service will call. For example:
public interface ITestMe { void TestMethod(Action<int> callback); }
In the application, when calling 'TestMethod' I would pass the callback method to hit after it has run, which will do something based on the parameters. Typically, in this case it's used like this:
...
testMe.TestMethod(
(ret) =>
{
if(ret < 0)
AddToErrorCollection(ret);
else
AddToSuccessCollection(ret);
}
);
What I'd like to do in MOQ is call that anonymous method with a range of values i.e. something like:
myMock.Setup(m => m.TestMethod(It.IsAny<Action<int>>())).... //Call that action!!??
Is there anyway to do that?
Is this even the correct way to do it?
try this:
myMock.Setup(m => m.TestMethod(It.IsAny<Action<int>>())).Callback<Action<int>>((action) => action(4));
although this seems a rather convoluted way to essentially test your callback method. Why not test it directly?