tags:

views:

469

answers:

2

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);
}
A: 

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.

meandmycode is correct, I just looked at what Do does and learned something. :)
+1  A: 

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);
}
Peter Morris