3
[Subject(typeof(OnceADayProcessor))]
public class When_processing_process_twice
{
    private static ICanBeProcessedOnceADay ProcessedOnceADay;

    private Establish context = () => { OnceADayProcessor.Now = () => new DateTime(2011, 1, 1, 0, 0, 0, 0); };

    private Because of = () =>
                             {
                                 ProcessedOnceADay = MockRepository.GenerateMock<ICanBeProcessedOnceADay>();
                                 ProcessedOnceADay.Process();
                                 ProcessedOnceADay.Process();
                             };

    private It should_execute = () => ProcessedOnceADay.AssertWasCalled(x => x.Expect(p => p.Process()));
    private It should_execute_only_once = () => ProcessedOnceADay.AssertWasNotCalled(x => x.Expect(p => p.Process()));
}

edited solution:

[Subject(typeof(OnceADayProcessor))]
public class When_processing_a_process_twice_at_the_same_day
{
    static ICanBeProcessedOnceADay canBeProcessedOnceADay;

    Establish context = () =>
    {
        canBeProcessedOnceADay = A.Fake<ICanBeProcessedOnceADay>();
    };

    Because of = () =>
    {
        OnceADayProcessor.Process(canBeProcessedOnceADay);
        OnceADayProcessor.Process(canBeProcessedOnceADay);
    };

    It should_execute_only_once = () => 
        A.CallTo(() => canBeProcessedOnceADay.Process()).MustHaveHappened(Repeated.Exactly.Once);
}
Anthony Mastrean
  • 21,850
  • 21
  • 110
  • 188
Rookian
  • 19,841
  • 28
  • 110
  • 180

3 Answers3

4
var mock = MockRepository.GenerateMock<ICanBeProcessedOnceADay>();
mock.Expect(a => a.Process()).Repeat.Times(1);
...
mock.VerifyAllExpectations();
Dmitry
  • 17,078
  • 2
  • 44
  • 70
4

I would replace the calls to stub.Expect() and stub.VerifyAllExpectations() with stub.AssertWasCalled(x => x.Process(), o => o.Repeat.Once()) in the It. If you have more than one expectation against the stub you can then put each assertion in one It and have them fail (or succeed) independently of each other.

The creation of the stub would go into Establish (essentially, creation of any dependencies and the System Under Test is part of the "arrange" phase in unit testing).

Also consider not to use GenerateMock but GenerateStub as mocks will likely lead to brittle tests when you call other methods than the ones specified with Expect. Libraries like FakeItEasy generally provide better and more discoverable APIs, are easier to learn and will make you fall into the "pit of success".

Alexander Groß
  • 10,200
  • 1
  • 30
  • 33
  • I dont understand why I should use a stub instead of mock. I thought I would need a mock, because I assert a call and no state. – Rookian Sep 10 '11 at 13:49
  • http://ayende.com/wiki/Rhino+Mocks+3.5.ashx#Thedifferencebetweenstubsandmocks Mocks will break tests, stubs don't. It's as easy as that. – Alexander Groß Sep 11 '11 at 09:58
3

If you want to ensure that a method is called only once, you need a strict mock:

var mock = MockRepository.GenerateStrictMock<IShouldOnlyBeCalledOnce>();
mock.Expect(a => a.Process()).Repeat.Once();

sut.Process(mock)

mock.VerifyAllExpectations();

If you just use GenerateMock, it will perform an "at least" check. This also goes for Repeats.Times(x) too.

Clarkeye
  • 889
  • 8
  • 9