Peter Morris
Peter Morris

Reputation: 23234

Rhino Mocks, returning a different result each time stubbed method is executed

In this example the .Stub returns a new memory stream. The same memory stream is returned both times. What I want is a new memory stream every time. My question is, how do I change the .Stub in order to make this test pass?

[TestMethod]
public void Meh()
{
    var mockFileSystem = MockRepository.GenerateMock<IFileSystemService>();
    mockFileSystem.Stub(fs => fs.CreateFileStream(null, FileMode.Append, FileAccess.Write, FileShare.None))
        .IgnoreArguments()
        .Return(new MemoryStream());

    var result1 = mockFileSystem.CreateFileStream(null, FileMode.Append, FileAccess.Write, FileShare.None);
    var result2 = mockFileSystem.CreateFileStream(null, FileMode.Append, FileAccess.Write, FileShare.None);
    Assert.AreNotSame(result1, result2);
}

Upvotes: 7

Views: 2313

Answers (2)

Peter Morris
Peter Morris

Reputation: 23234

The trick is to use WhenCalled to replace the previous Return operation:

[TestMethod]
public void Meh()
{
    var mockFileSystem = MockRepository.GenerateMock<IFileSystemService>();
    mockFileSystem.Stub(fs => fs.CreateFileStream(null, FileMode.Append, FileAccess.Write, FileShare.None))
        .IgnoreArguments()
        .Return(null) 

        //*****The return value is replaced in the next line!
        .WhenCalled(invocation => invocation.ReturnValue = new MemoryStream());

    var result1 = mockFileSystem.CreateFileStream(null, FileMode.Append, FileAccess.Write, FileShare.None);
    var result2 = mockFileSystem.CreateFileStream(null, FileMode.Append, FileAccess.Write, FileShare.None);
    Assert.AreNotSame(result1, result2);
}

Upvotes: 8

webpaul
webpaul

Reputation:

Depending on what version you are using there is an implicity Repeat.Once or Repeat.Any - From your test i think it is a Repeat.Any which was added recently. So I believe it is returning the same object since the new occurs in your inital statement, i.e. it is not a delegate that is executed on each call of the mocked method. To get what you want, do two expect calls, each with a repeat.once.

Upvotes: 0

Related Questions