我如何模拟引用私有对象实例的.NET代码?

问题描述 投票:1回答:2

我正在尝试编写以下代码以进行单元测试:

// 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());
        }
    }
}

现在,我模拟了Open()返回的Stream实例。这很简单。流对象也是MemoryStream,顺便说一句。

但是我不确定如何设置ReadToEnd() ..以返回我拥有的某些字符串内容。这是因为StreamReader实例对此方法是私有的。

我想提供一个可以设置的属性。

例如

public string AStreamReader { get; set; }

然后这样做..

// 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());
        }
    }
}

然后仅通过StreamReader属性传递模拟AStreamReader

但是我不是很想这样做。我觉得我在不必要地泄漏一些内部逻辑,而只是出于嘲笑!真正的用户永远都不会设置它,因此这感觉确实很肮脏。

c# .net unit-testing stream mocking
2个回答
5
投票

也许我丢失了一些东西,但是如果您能够模拟输入Stream,为什么还要模拟StreamReader

以下内容不适合您吗?

    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();
    }

}

0
投票

将修饰符设置为保护状态,并为其子类化。在这种情况下,这就是我们进行大多数测试的方式。

© www.soinside.com 2019 - 2024. All rights reserved.