繁体   English   中英

C#模拟嘲笑<StreamWriter>

[英]C# mocking Mock<StreamWriter>

我是C#模拟的新手,我尝试阅读一些代码,但其中一项测试失败,您能否向我解释下面的源代码正在尝试什么,何时会失败?

Mock<StreamWriter> _streamWriterMock;
string[] expectedLines;
.
.
.
foreach (var line in expectedLines)
{
    _streamWriterMock.Verify(a => a.Write(line), Times.Exactly(1));
}

校验
您可能要检查被测方法是否被调用,甚至检查该方法被调用了多少次。

只是为了重现问题,请尝试以下代码

class Program
{
    static void Main(string[] args)
    {
        var _streamWriterMock = new Mock<StreamWriter>("output.txt");
        string[] expectedLines= new []{"test","test"};

        foreach (var expectedLine in expectedLines)
        {
            _streamWriterMock.Object.Write(expectedLine);
        }
        foreach (var line in expectedLines)
        {
           _streamWriterMock.Verify(a=>a.Write(line),Times.Exactly(1));    
        }

    }
}

实际上,如果您尝试使用数组{"test","test"}模拟代码,则会出现异常
Expected invocation on the mock exactly 1 times, but was 2 times: a => a.Write("test")

但是,如果您的数组如下所示

string[] expectedLines= new []{"test","test1"};

您的模拟将正确执行

因此,您的verify将检查是否为相同的输入恰好一次调用了您的方法。 我认为代码的主要目标是省略两次编写相同的输出。

您的示例中的测试遍历了ExpectedLines数组中的所有字符串,并检查_streamWriterMock.Write(string value)是否对它们中的每一个调用了一次。 如果未调用Write或在任何字符串上多次调用Write,它将失败。

更新

通常,模拟的方法必须是虚拟的,并且取决于您的模拟框架,可能需要在调用之前设置模拟的方法,因此它可能根本不是有效的测试,因为StreamWriter是具体的类,而Write不是虚拟的方法。

鉴于嘲笑的StreamWriter

充其量, foreach循环可用于通过模拟来验证在测试对象的锻炼期间,模拟行WriteWrite方法上仅一次调用了预期的lines数组中的每个字符串。

如果任何预期的行被多次写入,则测试将失败。

查看起订量:快速入门-验证

以以下课程为例,该课程取决于StreamWriter

public class SubjectUnderTest {
    private StringWriter stringWriter;

    public SubjectUnderTest(StringWriter stringWriter) {
        this.stringWriter = stringWriter;
    }

    public void WriteLines(string[] lines) {
        foreach (var line in lines) {
            this.stringWriter.Write(line);
        }
    }
}

测试时可以模拟依赖关系,并且可以单独验证被测方法的功能。

例如。

[TestMethod]
public void TestMethod1() {
    //Arrange
    var _streamWriterMock = new Mock<StringWriter>();
    string[] expectedLines = new[] { "line1", "line2" };
    var subject = new SubjectUnderTest(_streamWriterMock.Object);

    //Act
    subject.WriteLines(expectedLines);

    //Assert
    foreach (var line in expectedLines) {
        _streamWriterMock.Verify(a => a.Write(line), Times.Exactly(1));
    }
}

但是,如果expectedLines重复了{ "lineN", "lineN" } ,则上述测试将失败,因为验证期望使用给定的字符串值精确地调用一次Write方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM