Clear call history of a mock - rhino-mocks

question: is it possible to clear the call history of a mock (or stub)?
( and with call history I don't mean the expected / recorded behaviour.)
The details:
I currently want am writing the following code with tests according the AAA syntax using NUnit and Rhino mocks.
public abstract class MockA
{
private bool _firstTime = true;
public void DoSomething()
{
if (_firstTime)
{
OnFirstDoSomething();
_firstTime = false;
}
}
public abstract void OnFirstDoSomething();
}
[TestFixture]
public class MockATest
{
[Test]
public void DoSomethingShouldSkipInitializationForSequentialCalls()
{
// Arrange
var mockA = MockRepository.GeneratePartialMock<MockA>();
mockA.Expect(x => x.OnFirstDoSomething()).Repeat.Any();
mockA.DoSomething(); // -> OnFirstDoSomething() is called
// here I want clear the call history of mockA
//Act
mockA.DoSomething(); // -> OnFirstDoSomething should NOT be called
mockA.DoSomething(); // -> OnFirstDoSomething should NOT be called
//assert
mockA.AssertWasNotCalled(x => x.OnFirstDoSomething());
}
}
For the readability I always try to focus the calls in the Assert section on the changes that occur within the Act section.
However, the arrange section in this test, contains a (required) action that influence the call history of mockA.
As a result the assert fails.
I known I could catch a 'change' in the call history using the construction below, but it makes the expected behaviour of this test less readable.
{
...
mockA.AssertWasCalled(x => x.OnFirstDoSomething(), opt => opt.Repeat.Once());
//Act
mockA.DoSomething();
//Assert
mockA.AssertWasCalled(x => x.OnFirstDoSomething(), opt => opt.Repeat.Once());
}
My question: is it possible to clear the call history of a mock (not recorded Expectations)?

You don't need to clear call history. Use Stub method instead of Expect in Arrange section:
[Test]
public void DoSomethingShouldSkipInitializationForSequentialCalls()
{
// Arrange
var mockA = MockRepository.GeneratePartialMock<MockA>();
// this is what you have to change
mockA.Stub(x => x.OnFirstDoSomething()).Repeat.Any();
mockA.DoSomething(); // -> OnFirstDoSomething() is called
// here I want clear the call history of mockA
//Act
mockA.DoSomething();
mockA.DoSomething();
//assert
mockA.AssertWasNotCalled(x => x.OnFirstDoSomething());
}

Related

Xunit Unit Testing for Dot Net core application

I recently started learning Unit Testing and now have the requirement write unit tests using Xunit and Moq for dot net core application.
I can write some very basic but when it comes to write them for complex classes , I am kind of stuck.
Below is the class I will be writing tests for.
public class AgeCategoryRequestHandler : IInventoryRequestHandler<InventoryRequest, HandlerResult>
{
private readonly IRepositoryResolver _repositoryResolver;
Hotels.HBSI.Logging.ILogger logger;
public AgeCategoryRequestHandler(IRepositoryResolver repositoryResolver, Hotels.HBSI.Logging.ILogger iLogger)
{
_repositoryResolver = repositoryResolver;
logger = iLogger;
}
public async Task<HandlerResult> Run(InventoryRequest inventoryRequest)
{
var result = await ProcessRequest(inventoryRequest);
return CreateResponse(inventoryRequest, result);
}
private async Task<int> ProcessRequest(InventoryRequest inventoryRequest)
{
logger.Info("AgeCategory requesthandler processrequest start");
var repository = _repositoryResolver.ResolveEstabAgeCategory();
if (repository is not null)
{
return await repository.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories)
.ConfigureAwait(false);
}
logger.Info("AgeCategory requesthandler processrequest complete");
return InernalError.reponotfound;
}
public HandlerResult CreateResponse(InventoryRequest inventoryRequest, int resultCount)
{
var requestCount = inventoryRequest.EstabAgeCategories.Count;
var handlerResult = new HandlerResult() { Id = RequestHandlerEnum.AgeCategrory.ToInt() };
if (requestCount > 0 && resultCount < requestCount)
{
handlerResult.IsSuccess = false;
handlerResult.ErrorCode = OTAErrorType.InvalidAgeCategory.ToInt();
}
else if (requestCount > 0 || requestCount == resultCount)
{
handlerResult.IsSuccess = true;
handlerResult.ErrorCode = 0;
}
return handlerResult;
}
}
Just to start , IRepositoryResolver and ILogger are in the constructor so I have created mock for these but unable to go beyond that as I am still in initial phase of learning.
Could someone explain me the steps/approach to accomplish this?.
Edit : What I have done so far is below ( can't figure out what are the things to be done and where to start or write )
Edit 2 : Did some more modifications to my test code , can someone comment if I am in right direction ? what else can I test ?
public class AgeCategoryRequestHandlerTest
{
private AgeCategoryRequestHandler _ageCategoryRequestHandler;
private readonly Mock<AgeCategoryRequestHandler> _ageCategory = new Mock<AgeCategoryRequestHandler>();
private readonly Mock<Hotels.HBSI.Logging.ILogger> _mockLogger = new Mock<Hotels.HBSI.Logging.ILogger>();
private readonly Mock<IRepositoryResolver> _mockRepositoryResolver = new Mock<IRepositoryResolver>();
public AgeCategoryRequestHandlerTest()
{
_ageCategoryRequestHandler = new AgeCategoryRequestHandler(_mockRepositoryResolver.Object, _mockLogger.Object);
}
[Fact]
public async void Testtt()
{
var fixture = new Fixture();
var inventory = fixture.Create<InventoryRequest>();
var hndlr = fixture.Create<HandlerResult>();
hndlr.ErrorCode = 0;
int resultCount = 3;
await _ageCategoryRequestHandler.Run(inventory);
HandlerResult response = _ageCategoryRequestHandler.CreateResponse(inventory, resultCount);
Assert.Equal(hndlr.ErrorCode, response.ErrorCode);
}
Tried running Chris B suggested code , was getting type conversion error EstabAgeCategories = new List<int>
Now I have used fixture for creating automatic objects and did some assert values. Below is the code sample
var fixture = new Fixture();
var inventoryRequest = fixture.Create<InventoryRequest>();
_mockRepository
.Setup(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories))
.ReturnsAsync(6);
_mockRepositoryResolver
.Setup(x => x.ResolveEstabAgeCategory())
.Returns(_mockRepository.Object);
// act
var result = await _ageCategoryRequestHandler.Run(inventoryRequest);
// assert
_mockRepository
.Verify(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories), Times.Once);
Assert.True(result.Id == 6);
Assert.True(result.ErrorCode == 0);
Assert.True(result.IsSuccess);
From the unit test code you've posted, it looks like you are getting confused on what to test.
Look at your class and identify your "public" interface i.e. what methods can be called from other parts of your code. You should really only test public methods. Private methods are usually tested via public methods.
Looking at AgeCategoryRequestHandler, you have two public methods - Run and CreateResponse. I would question whether CreateResponse needs to be public but we'll leave it for now. For each of these methods, you want to be asserting that the returned value is what you expect given the input value.
private AgeCategoryRequestHandler _ageCategoryRequestHandler;
// Not needed
private readonly Mock<AgeCategoryRequestHandler> _ageCategory = new Mock<AgeCategoryRequestHandler>();
private readonly Mock<Hotels.HBSI.Logging.ILogger> _mockLogger = new Mock<Hotels.HBSI.Logging.ILogger>();
private readonly Mock<IRepositoryResolver> _mockRepositoryResolver = new Mock<IRepositoryResolver>();
public AgeCategoryRequestHandlerTest()
{
_ageCategoryRequestHandler = new AgeCategoryRequestHandler(_mockRepositoryResolver.Object, _mockLogger.Object);
}
The set up of the unit test is going the right way - you have created mocks for your dependencies but I see you have created a mock for the class you are trying to test - this is not needed and can be removed. You want to be testing the actual class itself which you are initializing in the constructor.
public async Task<HandlerResult> Run(InventoryRequest inventoryRequest)
{
var result = await ProcessRequest(inventoryRequest);
return CreateResponse(inventoryRequest, result);
}
private async Task<int> ProcessRequest(InventoryRequest inventoryRequest)
{
_logger.LogInformation("AgeCategory requesthandler processrequest start");
var repository = _repositoryResolver.ResolveEstabAgeCategory();
if (repository != null)
{
return await repository.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories).ConfigureAwait(false);
}
_logger.LogInformation("AgeCategory requesthandler processrequest complete");
return 0;
}
We can test the public Run method by looking at the method and seeing what it is going to do when executed. Firstly, it's going to call a private method ProcessRequest. Inside ProcessRequest, the IRepositoryResolver dependency is going to be used. This means we need to "set up" this dependency in our unit test to satisfy the if (repository != null) condition.
I assume the IRepositoryResolver returns another interface (?) - something like:
public interface IRepository
{
Task<int> InsertUpdateEstabAgeCategoryDetail(List<int> x);
}
So in your unit test, you need to create a mock for the repository being returned from IRepositoryResolver:
private readonly Mock<IRepository> _mockRepository = new Mock<IRepository>();
Then, you need to set up the mock IRepositoryResolver to return the mock repository above:
_mockRepositoryResolver
.Setup(x => x.ResolveEstabAgeCategory())
.Returns(_mockRepository.Object);
This is to satisfy the if (repository != null) condition.
_mockRepository
.Setup(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories))
.ReturnsAsync(6);
Next, you need to set up the InsertUpdateEstabAgeCategoryDetail() method on the mock repository to return a value. This value is being returned by ProcessRequest() and then used to call CreateResponse(inventoryRequest, result) as the result parameter.
if (requestCount > 0 && resultCount < requestCount)
{
handlerResult.IsSuccess = false;
handlerResult.ErrorCode = (int)OTAErrorType.InvalidAgeCategory;
}
else if (requestCount > 0 || requestCount == resultCount)
{
handlerResult.IsSuccess = true;
handlerResult.ErrorCode = 0;
}
Now you can look at the CreateResponse method and by setting different values for inventoryRequest.EstabAgeCategories and setting up the mock _mockRepository.Setup(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories)).ReturnsAsync(6); to return different values, you can satisfy the different paths through the if statement.
CreateResponse is returning an instance of HandlerResult which in turn is being returned by Task<HandlerResult> Run. This is the returned object you want to make assertions on.
One of the unit test cases might look like this (I have not tested it myself):
[Fact]
public async Task GivenInventoryRequest_WhenRun_ThenHandlerResultReturned()
{
// arrange
var inventoryRequest = new InventoryRequest
{
EstabAgeCategories = new List<int>
{
1, 2, 3, 4, 5
}
};
_mockRepository
.Setup(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories))
.ReturnsAsync(6);
_mockRepositoryResolver
.Setup(x => x.ResolveEstabAgeCategory())
.Returns(_mockRepository.Object);
// act
var result = await _ageCategoryRequestHandler.Run(inventoryRequest);
// assert
_mockRepository
.Verify(x => x.InsertUpdateEstabAgeCategoryDetail(inventoryRequest.EstabAgeCategories), Times.Once);
Assert.True(result.Id == 0);
Assert.True(result.ErrorCode == 0);
Assert.False(result.IsSuccess);
}

FakeItEasy ControllerTest HttpGet Calls

I want to start using FakeItEasy for testing queries.
The tests I want to write should check if entities are returned on HttpGet calls (get all and get by Id)
The Controller:
public class ToDoController : ControllerBase
{
private readonly IMediator _mediator;
public ToDoController(IMediator mediator) =>
_mediator = mediator;
[HttpGet]
[Produces("application/json")]
[ProducesResponseType(typeof(IEnumerable<ToDoItem>), (int)HttpStatusCode.OK)]
public async Task<ActionResult<IEnumerable<ToDoItem>>> Get()
{
var result = await _mediator.Send(new ToDoItemsQuery(new
AllToDoItems())).ConfigureAwait(false);
if (result != null && result.Any())
{
return result.ToList();
}
throw new InvalidOperationException("TODO: error handling");
}
[HttpGet]
[Route("{id}")]
[Produces("application/json")]
[ProducesResponseType(typeof(ToDoItem), (int)HttpStatusCode.OK)]
public async Task<ActionResult<ToDoItem>> GetById(int itemId)
{
var result = await _mediator
.Send(new ToDoItemsQuery(new ToDoItemById(itemId)))
.ConfigureAwait(false);
if (result != null && result.Any())
{
return result.FirstOrDefault();
}
throw new InvalidOperationException("TODO: error handling");
}
}
}
The TestClass:
public class ToDoItemControllerTests : ControllerTestBase
{
private IMediator _mediator;
private ToDoController _sut;
public ToDoItemControllerTests()
{
_mediator = A.Fake<IMediator>();
_sut = new ToDoController(_mediator);
}
[TestMethod]
public async Task GetAllItemsAsync_SuccessTest()
{
A.CallTo(() => _mediator.Send(A<AllToDoItems>._,
A<CancellationToken>._)).Returns(A.CollectionOfFake<ToDoItem>(10));
var result = await _sut.Get();
Assert.IsNotNull(result);
A.CallTo(() => _mediator).MustHaveHappened();
}
[TestMethod]
public async Task GetItemByIdAsync_SuccessTest()
{
// Arrange
int itemId = 2;
var commandResult =
new List<ToDoItem>
{
new ToDoItem
{
Id = itemId
};
}
A.CallTo(() => MediatR.Send(A<ToDoItemById>._, A<CancellationToken>._)).Returns(commandResult);
// Act
var result = await _sut.GetById(itemId);
// Assert
Assert.IsNotNull(result);
A.CallTo(() => MediatR.Send(A<ToDoItemById>._, A<CancellationToken>._)).MustHaveHappened();
}
}
So in the first test I set up A.CallTo the interface IMediatR to return 10 ToDoItems.
During debug I see the _sut.Get() enter the controller, entering the correct method/api call.
The _mediator.Send() in the controller returns a Fake IEnumerable (not the 10 items i set up in the first Call.To in the testmethod, but an enumeration that yields no results).
Because of the result.Any() being false, the controller throws an InvalidOperationException
And I cannot even Assert the result.IsNotNull()
The second test I want to Test If 1 item is returned upon calling the API.
I set up (a) an itemId of type int for parameter,
(b) A mocked(?) List with 1 Item from the setup with the itemId and
(c) a call to the mediatR should return the mocked Listfrom (b)
I make the call from the test, in debug I see the call await _mediator.Sent() returning
A Fake Ienumerable of ToDoItem, result is not null, but because result.Any() is false,
the item doesn't get returned, and I get another InvalidOperationException
I feel like I'm missing something in the setup of the tests..
A Fake database Interface?
I don't want to chance my controller and make the if less restrictive, just so my test would pass
EDIT:
Even if I change the if condition to removing the Any condition
and I see the test entering the controller, returning "First Or Default" of the result,
The test fails on A Call To Must Have Happened.
Expected to find it once or more but no calls were made to the fake object.
This I really don't get, i actually see him making the call?!
I've browsed GitHub to find examples but the closest I found was Entities with methods, with those methods being defined in an interface. This is not the case here
Seeing as the official documentation doesn't make me any wiser I turn to SO <3
Thanks in advance!
In the first test, you configure the call to Send with an argument of type AllToDoItems. But in the controller, you actually call Send with a TodoItemsQuery. So the call doesn't match, and the default (unconfigured) behavior, which is to return a fake IEnumerable, applies. You need to configure the call like this:
A.CallTo(() => _mediator.Send(A<TodoItemsQuery>._,
A<CancellationToken>._)).Returns(A.CollectionOfFake<ToDoItem>(10));
In the second test, the problem is the same, with ToDoItemById instead of AllToDoItems

Difference Stub Fixture

I am learning codeception and I wonder what is the difference between stubs and fixtures.
Both help me to load well-defined data and kepp tessts simple.
But when do I use
\Codeception\Util\Stub and when do I use
\Codeception\Util\Fixtures
So a stub is what Codeception uses to mock objects. In short, mocking is creating objects that simulate the behaviour of real objects.
Here is an example:
class UpdateBalance
{
public $balanceRepository;
public function __construct(BalanceRepositoryInterface $balanceRepository)
{
$this->balanceRepository = $balanceRepository;
}
public function subtract($amount, $id)
{
$updatedAmount = $this->balanceRepository->subtract($amount, $id);
if ($updatedAmount < 0) {
throw NegativeBalanceException($updatedAmount, $id);
}
return $updatedAmount;
}
}
class UpateBalanceTest extends PHPUnit_Framework_TestCase
{
public function testSubtractThrowsNegativeBalanceException()
{
$balanceRepository = Stub::make(
'BalanceRepositoryInterface'
array(
'subtract' => Stub::atLeastOnce(function() { return -100 })
)
);
$updateBalance = new UpdateBalance($balanceRepository);
$this->expectException(NegativeBalanceException::class);
$updateBalance->subtract(100, 1);
}
}
Note that we don't have a BalanceRepsository class. We have used Codeception stubs and pretended that the BalanceRepository class exists. By pretending it exists we can test the functionality of the UpdateBalance::subtract function by checking that the NegativeBalanceException is thrown.
Fixtures on the other hand would be for sharing test data throughout all your tests. If we use the UpdateBalance::subtract() example again, we could stress test the amount field ensuring it throws the correct exception depending on the amount being passed through:
// In some bootstrap or setup function
Fixtures::add('zero-amount', 0);
Fixtures::add('negative-amount', -1);
Fixtures::add('string-negative-amount', '-1');
class UpdateBalance
{
// ...
public function subtract($amount, $id)
{
if ($amount < 0) {
throw new
}
// ...
}
}
class UpateBalanceTest extends PHPUnit_Framework_TestCase
{
// ...
public function testSubtractThrowsCantSubtractNegativeAmountException()
{
$balanceRepository = Stub::make(
'BalanceRepositoryInterface'
);
$updateBalance = new UpdateBalance($balanceRepository);
$this->expectException(CantSubtractNegativeAmountException::class);
$updateBalance->subtract(Fixture::get('negative-amount'), 1);
}
}
Now we can use our pre-defined fixtures throughout all our tests. I would like to point out that using fixtures in the above example would probably be overkill, but for more complex test data like checking hexadecimal values are valid then it would be a lot more useful.

Structuring tests (or property) for this reactive ui scenario

I'm not sure the correct way to structure this test. I've got a view model here:
public class ViewModel
{
public ReactiveCommand PerformSearchCommand { get; private set; }
private readonly ObservableAsPropertyHelper<bool> _IsBusy;
public bool IsBusy
{
get { return _IsBusy.Value; }
}
public ViewModel(IAdventureWorksRepository _awRepository)
{
PerformSearchCommand = new ReactiveCommand();
PerformSearchCommand.RegisterAsyncFunction((x) =>
{
return _awRepository.vIndividualCustomers.Take(1000).ToList();
}).Subscribe(rval =>
{
CustomerList = rval;
SelectedCustomer = CustomerList.FirstOrDefault();
});
PerformSearchCommand.IsExecuting.ToProperty(this, x => x.IsBusy, out _IsBusy);
PerformSearchCommand.Execute(null); // begin executing immediately
}
}
The dependency is a data access object to AdventureWorks
public interface IAdventureWorksRepository
{
IQueryable<vIndividualCustomer> vIndividualCustomers { get; }
}
Finally, my test looks something like this:
[TestMethod]
public void TestTiming()
{
new TestScheduler().With(sched =>
{
var repoMock = new Mock<IAdventureWorksRepository>();
repoMock.Setup(x => x.vIndividualCustomers).Returns(() =>
{
return new vIndividualCustomer[] {
new vIndividualCustomer { FirstName = "John", LastName = "Doe" }
};
});
var vm = new ViewModel(repoMock.Object);
Assert.AreEqual(true, vm.IsBusy); //fails?
Assert.AreEqual(1, vm.CustomerList.Count); //also fails, so it's not like the whole thing ran already
sched.AdvanceTo(2);
Assert.AreEqual(1, vm.CustomerList.Count); // success
// now the customer list is set at tick 2 (not at 1?)
// IsBusy was NEVER true.
});
}
So the viewmodel should immediately begin searching upon load
My immediate problem is that the IsBusy property doesn't seem to get set in the testing scheduler, even though it seems to work fine when I run the code normally. Am I using the ToProperty method correctly in the view model?
More generally, what is the proper way to do the full 'time travel' testing when my object under test has a dependency like this? The issue is that unlike most testing examples I'm seeing, the called interface is not an IObservable. It's just a synchronous query, used asynchronously in my view model. Of course in the view model test, I can mock the query to do whatever rx things I want. How would I set this up if I wanted the query to last 200 ticks, for example?
So, you've got a few things in your code that is stopping you from getting things to work correctly:
Don't invoke commands in ViewModel Constructors
First, calling Execute in the constructor means you'll never see the state change. The best pattern is to write that command but not execute it in the VM immediately, then in the View:
this.WhenAnyValue(x => x.ViewModel)
.InvokeCommand(this, x => x.ViewModel.PerformSearchCommand);
Move the clock after async actions
Ok, now that we can properly test the before and after state, we have to realize that after every time we do something that normally would be async, we have to advance the scheduler if we use TestScheduler. This means, that when we invoke the command, we should immediately advance the clock:
Assert.IsTrue(vm.PerformSearchCommand.CanExecute(null));
vm.PerformSearchCommand.Execute(null);
sched.AdvanceByMs(10);
Can't test Time Travel without IObservable
However, the trick is, your mock executes code immediately, there's no delay, so you'll never see it be busy. It just returns a canned value. Unfortunately, injecting the Repository makes this difficult to test if you want to see IsBusy toggle.
So, let's rig the constructor a little bit:
public ViewModel(IAdventureWorksRepository _awRepository, Func<IObservable<List<Customer>>> searchCommand = null)
{
PerformSearchCommand = new ReactiveCommand();
searchCommand = searchCommand ?? () => Observable.Start(() => {
return _awRepository.vIndividualCustomers.Take(1000).ToList();
}, RxApp.TaskPoolScheduler);
PerformSearchCommand.RegisterAsync(searchCommand)
.Subscribe(rval => {
CustomerList = rval;
SelectedCustomer = CustomerList.FirstOrDefault();
});
PerformSearchCommand.IsExecuting
.ToProperty(this, x => x.IsBusy, out _IsBusy);
}
Set up the test now
Now, we can set up the test, to replace PerformSearchCommand's action with something that has a delay on it:
new TestScheduler().With(sched =>
{
var repoMock = new Mock<IAdventureWorksRepository>();
var vm = new ViewModel(repoMock.Object, () =>
Observable.Return(new[] { new vIndividualCustomer(), })
.Delay(TimeSpan.FromSeconds(1.0), sched));
Assert.AreEqual(false, vm.IsBusy);
Assert.AreEqual(0, vm.CustomerList.Count);
vm.PerformSearchCommand.Execute(null);
sched.AdvanceByMs(10);
// We should be busy, we haven't finished yet - no customers
Assert.AreEqual(true, vm.IsBusy);
Assert.AreEqual(0, vm.CustomerList.Count);
// Skip ahead to after we've returned the customer
sched.AdvanceByMs(1000);
Assert.AreEqual(false, vm.IsBusy);
Assert.AreEqual(1, vm.CustomerList.Count);
});

Question about Rhino Mock (RhinoAutoMocker)

I have a question about Rhino Mock.
I am trying to put restriction on what methods could be called from the method that is under test.
Lets say I have a method that I am writing the Unit Test against like this:
public void MyMethod()
{
var test = _Repository.Get(2);
_Services.DoSomething(test);
}
what I do right now is something like this :
[Test]
public void TestMethod()
{
var mock1 = CreateMock<IRepository>();
var mock2 = CreateMock<IServices)();
mock1.Expect(x => x.Get(1).IgnoreArguments().Return(new Poo()).Repeat.Once();
mock2.Expect(x => x.DoSomething(new Something()).IgnoreArguments().Repeat.Once();
ClassUnderTest.MyMethod();
mock1.VerifyAllExpectations();
mock2.VerityAllExpectations();
}
this is fine but what I want is to prevent somebody to change the method like this:
public void MyMethod()
{
var test = _Repository.Get(2);
var test = _Repository.Save(test);
_Services.DoSomething(test);
}
As you can see Save method on Repository is called, so this is dangerous obviously because if somebody by mistake add that line there we will be in trouble.
How can I restrict someond from doing that ? Thanks.
There are a few options:
Strict Mocks
Strict mocks throw an exception if they are called in a way that doesn't match an expectation. You can create strict mocks like this:
var mocks = new MockRepository();
var fooStrictMock = mocks.StrictMock<IFoo>();
.Repeat.Never()
If you are only interested in preventing calls to just one particular method, you can use the .Repeat.Never() quantifier on an expectation like this:
mock1.Expect(x => x.Save(null)).IgnoreArguments().Repeat.Never();
AssertWasNotCalled
You can call AssertWasNotCalled at the end of your test like this:
var repositoryStub = MockRepository.GenerateStub<IRepository>();
repositoryStub.Stub(x => x.Get(2)).Return(...);
var underTest = new UnderTest(repositoryStub);
underTest.DoSomething();
repositoryStub.AssertWasNotCalled(x => x.Save(Arg<Thing>.Is.Anything));