Question

I have the following code I'm trying to write a unit test for:

// Grab all of the content.
var rawContent = new StringBuilder();
foreach (var fileInfo in response.Files)
{
    using (var stream = fileInfo.VirtualFile.Open())
    {
        using (var streamReader = new StreamReader(stream))
        {
            rawContent.Append(streamReader.ReadToEnd());
        }
    }
}

Now, I have mocked the Stream instance that Open() returns. That's easy. The stream object is also a MemoryStream, btw.

But I'm not sure how to setup the ReadToEnd() .. to return some string content I have. This is because the StreamReader instance is private to this method.

I thought of providing a Property which can be set.

eg.

public string AStreamReader { get; set; }

then doing this ..

// Grab all of the content.
var rawContent = new StringBuilder();
foreach (var fileInfo in response.Files)
{
    using (var stream = fileInfo.VirtualFile.Open())
    {
        using (var streamReader = AStreamReader ?? new StreamReader(stream))
        {
            rawContent.Append(streamReader.ReadToEnd());
        }
    }
}

and then just passing a mock StreamReader through the AStreamReader property.

But I don't really want to do this. I feel that I'm leaking some internal logic, unnecessarily, and only for mocking! A real user will never set that, so that feels like a really dirty thing to do.

Was it helpful?

Solution

Perhaps I'm missing something but if you are able to mock the input Stream, why do you need to mock the StreamReader?

Does the following not work for you?

    private string ReadFromResponseFiles(Stream[] inputs)
    {
        var rawContent = new StringBuilder();
        foreach (var stream in inputs)
        {
            using (stream)
            {
                using (var streamReader = new StreamReader(stream))
                {
                    rawContent.Append(streamReader.ReadToEnd());
                }
            }
        }

        return rawContent.ToString();
    }

    [Test]
    public void Can_read_files()
    {
        var file1 = new MemoryStream(Encoding.UTF8.GetBytes("Foo"));
        var file2 = new MemoryStream(Encoding.UTF8.GetBytes("Bar"));

        var result = ReadFromResponseFiles(new[] { file1, file2 });
        Assert.AreEqual("FooBar", result);

        file1.Dispose();
        file2.Dispose();
    }

}

OTHER TIPS

Set the modifier as protected, and subclass it. It's how we do with most of our tests, in such cases as this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top