Search code examples
c#unit-testingmoqxunitmemorystream

moq verify method was called with stream of data


I have a method that calls another method with a stream. I would like to test that the data inserted in the first method is what is sent in the second.

public MyMessage Parse(byte[] data)
{
    return myDependency.Read(new MemoryStream(data))
}

In my test, I have something like the following

byte [] mockData = { 116, 101, 115, 116};

sut.Parse(mockData);

mockDependency.Verify(x=>x.Read(...));

Now my question is, what is the correct thing I should have in place of ...?

I can do something like (It.IsAny<MemoryStream>()), but that does not actually verify that it was called with the given data.

I tried something like It.Is<MemoryStream>(s=>s.Equals(new MemoryStream(data))) but that failed.

Is there a way for me to test that the data sent to Parse is the same data send in the memory stream to Read?


Solution

  • I tried something like It.Is<MemoryStream>(s=>s.Equals(new MemoryStream(data))) but that failed.

    In this case it could have been done like

    mockDependency.Verify(_ => _.Read(It.Is<MemoryStream>( s => 
        Enumerable.SequenceEqual(s.ToArray(), data))));
    

    by comparing the byte arrays

    You can also try capturing the passed argument so that is can be better inspected during assertion

    For example

    // Arrange
    byte [] expectedData = { 116, 101, 115, 116 };
    byte [] actualData = null;
    
    //...
    
    mockDependency
        .Setup(_ => _.Read(It.IsAny<MemoryStream>()))
        .Callback((MemoryStream ms) => actualData = ms.ToArray())
        .Returns(/* MyMessage here*/)
        .Verifiable();
    
    // Act
    sut.Parse(expectedData);
    
    //Assert
    mockDependency.Verify(); //verify that setup was invoked as expected
    //using FluentAssertions to check data
    actualData.Should().NotBeNull()
    .And.BeEquivalentTo(expectedData);
    

    Note that Fluent Assertions was used to simplify the assertion of the collection.