Reusing a verified Mock - c#

I am doing ordered expectations in rhino mocks as described by ayende in this post. My code looks something like this:
using (_mocks.Ordered())
{
Expect.Call(() => _myMock.CallA());
Expect.Call(() => _myMock.CallB(40));
Expect.Call(() => _myMock.CallA());
}
_mocks.ReplayAll();
_myObjectUnderTest.DoStuff();
_mocks.VerifyAll();
After this I would like to add more expectations and test more of my object's methods. I want to do this because I have some basic test methods that do some setup on my test object, and I do not want to have to retest that functionality, so I just call the earlier test method. If I try and add more expectations after VerifyAll() I get an exception: "This action is invalid when the mock object is in verified state."
Part of my problem is that I don't really understand what all of the replay/verify stuff is doing, I just copied code. I am using strict mocks, so any setup code must have matching expectations or it fails. I do not want to duplicate the expectations for my setup code.
Is there a way to reset the mock to be ready to start over in some way?

Short answer: no. Now on to the long answer.
What the replay and verify stuff does is this. Before you call ReplayAll, you are telling Rhino what you expect the methods are going to do. You in a sense are recording calls to the mock objects you've created.
After you've recorded the method calls, you call ReplayAll telling Rhino you're now going to do 'something' that should execute the methods as recorded.
Last, you call VerifyAll asking Rhino to verify whether the methods were actually called as you've recorded them.
Now on to why you really should not want to re-use the mocks. With unit testing/TDD, your unit test should test as little as possible. This is to keep your unit tests simple and transparent. The whole idea of unit testing is that many many many small tests as a whole test the entire system.
For a very good presentation on TDD explaining this and other subjects, see http://www.infoq.com/presentations/integration-tests-scam.
P.S.: One small detail: As long as the methods don't return a result, you can write:
using (_mocks.Ordered())
{
Expect.Call(() => _myMock.CallA());
Expect.Call(() => _myMock.CallB(40));
Expect.Call(() => _myMock.CallA());
}
as:
using (_mocks.Ordered())
{
_myMock.CallA();
_myMock.CallB(40);
_myMock.CallA());
}
(at least with the latest version of Rhino)

Short answer: yes
Longer answer: Try the following
[Test]
public void RhinoMock_PerformMultipleChecks()
{
var myMock = MockRepository.GenerateDynamicMockWithRemoting<IComparable>();
// first round of checks
myMock.Expect(x => x.CompareTo("123")).Return(1);
myMock.Expect(x => x.CompareTo("-12")).Return(-1);
Assert.AreEqual(1, myMock.CompareTo("123"));
Assert.AreEqual(-1, myMock.CompareTo("-12"));
myMock.VerifyAllExpectations();
// reset
myMock.BackToRecord();
myMock.Replay();
// next round of checks
myMock.Expect(x => x.CompareTo(1.23)).Return(1);
myMock.Expect(x => x.CompareTo(-12)).Return(-1);
Assert.AreEqual(1, myMock.CompareTo(1.23));
Assert.AreEqual(-1, myMock.CompareTo(-12));
myMock.VerifyAllExpectations();
// reset
myMock.BackToRecord();
myMock.Replay();
// final round of checks
myMock.Expect(x => x.CompareTo(1.23m)).Return(1);
myMock.Expect(x => x.CompareTo(-12m)).Return(-111);
Assert.AreEqual(1, myMock.CompareTo(1.23m));
Assert.AreEqual(-111, myMock.CompareTo(-12m));
myMock.VerifyAllExpectations();
}

Related

What is the FakeItEasy equivalent of the Moq VerifyNoOtherCalls() method

I'm currently a Moq user and I'm researching other mocking frameworks.
When unit testing I frequently call _mock.VerifyNoOtherCalls() so I can be certain there are no unexpected interactions beyond the ones that I have already verified.
I've searched the FakeItEasy docs and cannot find the equivalent option in their framework. Can anyone suggest how I might do this?
Strict fakes
FakeItEasy supports strict fakes (similar to strict mocks in Moq):
var foo = A.Fake<IFoo>(x => x.Strict());
This will fail the moment an unexpected call is made.
Semi-strict fakes
It is also possible to configure all calls directly:
A.CallTo(fakeShop).Throws(new Exception());
and combine this with specifying different behaviors for successive calls, however in this case, there's no benefit to doing so over using a strict fake, as a strict fake will give better messages when unconfigured methods are called. So if you want to configure some methods to be called a limited number of times, you could
var fakeShop = A.Fake<IShop>(options => options.Strict());
A.CallTo(() => fakeShop.GetTopSellingCandy()).Returns(lollipop).Once();
A.CallTo(() => fakeShop.Address).Returns("123 Fake Street").Once();
fakeShop.GetTopSellingCandy() and fakeShop.Address can be called once, the second time it will fail.
Arbitrary checks
If you want to check if no calls are made at arbitrary points in the test:
A.CallTo(fakeShop).MustNotHaveHappened();
It might be better to filter out some of the methods that can be executed while debugging:
A.CallTo(a)
.Where(call => call.Method.Name != "ToString")
.MustNotHaveHappened();
You don't want a failing test because you hovered over the variable.

Rhino Mocks Why Can't I Mock a Property?

I spent a few days writing a test, then had to add a property at the last minute to fix one of the issues I found in writing my test. Since adding that property I have been stuck just trying to get the mocking framework to function.
Here is my code.
using (_mockRepository.Record())
{
_mockBattleDao.Expect(b => b.GetUnprocessedActions(gameId, round)).Return(roundResolvingItems);
_mockDao.Expect(b => b.GetMidGameCharacterStats(gameId, round)).Return(midGameCharacterStats);
_mockBattleDao.Expect(b => b.GetAmbientCharacterBuffs(_mockTiersHelper, gameId, round)).Return(new List<Buff>());
_mockBattleDao.Expect(b => b.GetActiveTriggerBuffs(_mockTiersHelper, gameId, round)).Return(triggerBuffs);
_mockBattleDao.Expect(b => b.GetActiveAmbientBuffs(_mockTiersHelper, gameId, round)).Return(new List<Buff>());
_mockDao.Expect(b => b.GetGame(gameId)).Return(new Common.Entities.Game { CompletionType = "single party down" });
_mockDao.Expect(b => b.GetAbilityById(1337)).Return(ability).Repeat.Times(3);
_mockDao.Expect(b => b.GetAbilityById(1727)).Return(attackAbility).Repeat.Times(4);
_mockTiersHelper.Expect(b => b.AddStatistic(Arg<StatAndCount>.Is.Anything)).Repeat.Times(3);
SetupResult.For(_mockTiersHelper.Round).Return(round);
}
TiersCalculationContainer container;
using (_mockRepository.Playback())
{
container = engine.ProcessTiers();
}
I Know the AAA syntax is the new hotness but I have a large test that is complete but for this and I don't want to go back and rewrite.
When code execution reaches the closing "}" of the "Playback" using I get this exception:
ExpectationViolationException
TiersCalculationContainer.get_Round(); Expected #1, Actual #0.
When debugging the test the property "Round" is read correctly and retursn the value I mocked for it so I know it was called.
I can't find any information online about this. There seems to be about 100 ways to mock a property in Rhino mocks. None of them are working and this is getting really frustrating.
I have also tried mocking all of these ways as well (and more)
_mockTiersHelper.Expect(b => b.Round).Return(round);
Expect.Call(_mockTiersHelper.Round).PropertyBehavior();
_mockTiersHelper.Round = round;
That is a lot of expectations for one test, I would recommend testing the behavior of each of these objects separately and then testing only that they are called properly at the integration point.
Aside from that I think your problem is a logic issue not a syntax issue, if you are setting up the mock according to the documentation and getting an unexpected behavior its a bug in your code or your test.
I think the answer to this may be that this is a bug. I dumped Rhino and went back to Moq. 10 minutes and I was up and running. Now my tests pass. Thank you Moq!

What's the correct way to use Stubs and Mocks?

Here's my example:
[TestMethod]
public void NewAction_should_return_IndexAction()
{
NewViewModel viewModel = new NewViewModel()
{
Name = "José Inácio Santos Silva",
Email = "joseinacio#joseinacio.com",
Username = "joseinacio"
};
//IsUserRegistered is used to validate Username, Username is unique.
_mockAuthenticationService.Setup(x => x.IsUserRegistered(viewModel.Username )).Returns(false);
//IsUserRegistered is used to validate Email, Email is unique.
_mockUsuarioRepository.Setup(x => x.GetUserByEmail(viewModel.Email));
_mockDbContext.Setup(x => x.SaveChanges());
_mockUsuarioRepository.Setup(x => x.Add(It.IsAny<User>()));
_userController = new UserController(_mockUsuarioRepository.Object, _mockDbContext.Object, _mockAuthenticationService.Object);
ActionResult result = _userController.New(viewModel);
result.AssertActionRedirect().ToAction("Index");
_mockAuthenticationService.VerifyAll();
_mockUsuarioRepository.VerifyAll();
_mockDbContext.VerifyAll();
}
I have read some tutorials and they say that we should use only one mock per test.
But look at my test, it use 3 mocks, to check if my Action is working the right way I need to check these 3 mocks, do not agree?
How do I make this test in the correct way?
Each unit test should test only one thing.
In your unit test you are testing three mock objects. If the mockAuthenticationService fails, this will be reported and the unit test will stop there. Any errors with the other Mock objects are not reported and are effectively hidden.
In this situation you should create three unit tests, and in each one verify only one of the Mock objects. The rest are just used as stubs. (A stub is exactly the same as a Mock object, except you dont call VerifyAll on it at the end)
To avoid duplication and wasted effort, you should refactor that unit test so that most of the code is in a separate method. Each of the three unit tests calls this method and then verifies a single Mock.
You also have a test to ensure the correct redirect is called. This should also be in a separate test.
Quite simply:
[TestMethod]
public void NewAction_should_checkUserRegistered()
{
SetupTest();
_mockAuthenticationService.VerifyAll();
}
[TestMethod]
public void NewAction_should_GetUserByEmail()
{
SetupTest();
_mockUsuarioRepository.VerifyAll();
}
[TestMethod]
public void NewAction_should_SaveDBContext()
{
SetupTest();
_mockDbContext.VerifyAll();
}
[TestMethod]
public void NewAction_should_return_Redirects_Action()
{
var novoActionResult = SetupTest();
novoActionResult.AssertActionRedirect().ToAction("Index");
}
Short answer: "only one mock per test." is ambiguous. Use as many fakes as you need to isolate the code under test to a "unit" that is testing one condition.
It should be phrased: Only test one thing per test. If you are checking the state of more than one mock object you are probably testing more than one thing.
Long answer:
There is a lot to answer here to get the unit test written according to the best practices I have come across.
Common terminology from (The Art of Unit Testing), which I hope will come to be common:
Fake - an object that isolates the code under test from the rest of the application.
Stub - a simple fake object.
Mock - a fake object that stores what is passed to it, that you can inspect to verify the test.
Stubs and Mocks are both types of fake.
"only one mock per test." is wrong. You use as many fakes as you need to fully isolate the code under test from the rest of the application. If a method takes no parameters, there's nothing to fake. If a method takes a simple data type e.g. int, string, that doesn't have any complex behaviour, you don't need to fake it. If you have 2 repositories, context, a service object passed in, fake all of them, so no other production methods are being called.
You should have one condition per test as #Mongus Pong has said.
Test naming convention: MethodUnderTest_Condition_ExpectedBehaviour in this case you cannot do that as you have got more than one condition tested.
Test pattern: Arrange, Act, Assert. From your test, it seems as that is what you have done, but you have are arranging using private members. You should replace these with variables in each test, since the running order of tests is not always enforced, the state of these variables cannot be guaranteed, making your tests unreliable.
Buy a copy of "The Art of Unit Testing" http://artofunittesting.com/ it will answer a lot of more of your questions and is a great investment; one of the books that I'd grab if the office caught fire.
IMHO mocks and stubs are not that unique defined - every author uses them slightly different.
As I understand stubs "mock" behavior or "output" while you use mocks for example to check "input" into the mocked object/interface (like the Verify-Methods in MOQ).
If you see it this way then yes I too think you should only use one Mock because you should only test one thing - if you see it more like the stubs to inject testable interfaces then it's impossible to do.
If the VerifyAll is really needed here you indeed use 3 mocks, but I don't think they are nedded.
The best way to use Mock and stubs with Dev Magic Fake, so you can mock the UI and the DB for more information see Dev Magic Fake on codePlex
http://devmagicfake.codeplex.com/
Thanks
M.Radwan

How do I mock HttpResponseBase.End()?

I'm using Moq to create a mock object of HttpResponseBase. I need to be able to test that HttpResponseBase.End() was called in my library. To do this, I specify some text before the call and some text after. Then I check that only the text before the call to End() is present in HttpResponseBase.Output.
The problem is, I can't figure out how to mock HttpResponseBase.End() so that it stops processing, like it does in ASP.NET.
public static HttpResponseBase CreateHttpResponseBase() {
var mock = new Mock<HttpResponseBase>();
StringWriter output = new StringWriter();
mock.SetupProperty(x => x.StatusCode);
mock.SetupGet(x => x.Output).Returns(output);
mock.Setup(x => x.End()) /* what do I put here? */;
mock.Setup(x => x.Write(It.IsAny<string>()))
.Callback<string>(s => output.Write(s));
return mock.Object;
}
It is a bit unclear to me what it is you are trying to achieve, but from your description, it sounds like you are attempting to get your Abstraction to behave like a particular implementation. In other words, because HttpResponse.End() has a certain behavior, you want your Mock to have the same behavior?
In general, that is not particularly easy to do with Moq, since it has no concept of ordered expectations (unlike RhinoMocks). There is, however, a feature request for it.
You might be able to use a Callback together with setting up the End method to toggle a flag that determines any further behavior of the Mock, but it's not going to be particularly pretty. I'm thinking about something like this:
bool ended = false;
var mock = new Mock<HttpResponseBase>();
mock.Setup(x => x.End()).Callback(() => ended = true);
// Other setups involving 'ended' and Callbacks
Then have all other Setups have dual implementatations based on whether ended is true or false.
It would be pretty damn ugly, so I'd seriously reconsider my options at this point. There are at least two directions you can take:
Make a Fake implementation of HttpResponseBase instead of using Moq. It sounds like you are expecting such specific behavior of the implementation that a Test Double with embedded logic sounds like a better option. Put shortly, a Fake is a Test Double that can contain semi-complex logic that mimics the intended production implementation. You can read more about Fakes and other Test Doubles in the excellent xUnit Test Patterns book.
Reconsider your initial assumptions. It sounds to me like you are tying your client very closely to a particular behavior of HttpResponseBase, so you may be violating the Liskov Substitution Principle. However, I may be mistaken, as a method called 'End' carries certain connotations beyond the purely semantic, but still, I'd personally consider if a better design was possible.

How to verify that method was NOT called in Moq?

How do I verify that method was NOT called in Moq?
Does it have something like AssertWasNotCalled?
UPDATE: Starting from Version 3.0, a new syntax can be used:
mock.Verify(foo => foo.Execute("ping"), Times.Never());
Run a verify after the test with the Times.Never() option.
_mock.Object.DoSomething()
_mock.Verify(service => service.ShouldntBeCalled(), Times.Never());
UPDATE: Since version 3, check the update to the question above or Dann's answer below.
Either, make your mock strict so it will fail if you call a method for which you don't have an expect
new Mock<IMoq>(MockBehavior.Strict)
Or, if you want your mock to be loose, use the .Throws( Exception )
var m = new Mock<IMoq>(MockBehavior.Loose);
m.Expect(a => a.moo()).Throws(new Exception("Shouldn't be called."));
Stolen from: John Foster's answer to the question, "Need help to understand Moq better"
One of the things that you might want to test is that the pay method
does not get called when a person aged over 65 is passed into the
method
[Test]
public void Someone_over_65_does_not_pay_a_pension_contribution() {
var mockPensionService = new Mock<IPensionService>();
var person = new Person("test", 66);
var calc = new PensionCalculator(mockPensionService.Object);
calc.PayPensionContribution(person);
mockPensionService.Verify(ps => ps.Pay(It.IsAny<decimal>()), Times.Never);
}
This does not work in recent versions of Moq (since at least 3.1), it should be specified in the Verify method as mentioned in the
answer.
Actually, it's better to specify .AtMost(0) after the Returns statement.
var m = new Mock<ISomething>();
m.Expect(x => x.Forbidden()).Returns("foo").AtMost(0);
Although the "throws" also works, AtMost(0) is more expressive IMHO.
Using VerifyNoOtherCalls (requires Moq 4.8 or later)
This answer is an indirect approach. Instead of checking that a particular method wasn't called, you check that no unexpected calls were made in general.
Consider that a thorough test of a mock does 2 things:
Verify that all expected calls were made
Verify that no unexpected calls were made
If you're already doing step 1, adding step 2 is trivial:
// Step 1 (if relevant - see note below)
mock.Verify(..., Times.Exactly(2));
mock.Verify(..., Times.Once());
// ...
// Step 2
mock.VerifyNoOtherCalls();
Notes
If you omit step 1, step 2 will simply ensure no calls were made to the mock at all.
This does not require a strict mock.
Source: Moq Quickstart
I realise this is a very old question, but it just appeared in my sidebar, and I'd like to add my solution.
Many unit tests appear to mock several functions, as part of the setup, but then aren't used during the test.
Surely it's better to enable strict mocking (which means anything not explicitly setup will throw an exception), and then don't set up any functions you don't expect to be called. Or to put it another way, only set up the functions that one test expects to be called, and anything else will thrown an exception.
var thingBeingTested = new Mock<IThink>(MockBehaviour.Strict);
thingBeingTested.ThisWillThrowAnExceptionBecauseItHasNotBeenMocked();
Suppose you have this method and you want to test that it's not being called
//Setup
var databaseSessionMock = new Mock<IDatabaseSession>();
databaseSessionMock.Setup(m => m.Commit()).Returns(true).Verifiable();
RepositoryFactory.Configure<IDatabaseSession>(databaseSessionMock.Object);
you can test like this
databaseSessionMock.Verify(m => m.Commit(It.IsAny()), Times.Never(), "Database Session mock object was not used");
Use .AtMostOnce();
After the real test, call the method again. If it throws an exception, it was called.

Categories

Resources