c#:如何验证按特定顺序调用方法?

时间:2009-10-02 00:07:43

标签: c# unit-testing mocking rhino-mocks

我有以下课程:

public class Script
{
    IPrinter _printer;

    public Script(IPrinter printer)
    {
        _printer = printer;
    }

    public void Print(TextWriter writer)
    {
        _printer.PrintComment(writer, "lolz");
        writer.WriteLine("omg this complicates things";
        _printer.PrintSpecial(writer);
        if (signoff)
            _printer.PrintComment(writer, "kthxbye");
    }
}

如何设置测试以声明使用正确的参数以正确的顺序调用打印机方法?

我可以手动创建一个'假'打印机并对编写器进行状态测试,但由于上下文很大(特别是因为脚本也在与编写器一起工作),我想避免它。

我正在使用nunit和rhino模拟器。任何关于体系结构更改的想法或模拟程序,以使这更容易测试,这是值得赞赏的。不幸的是,我正在使用的真实代码更复杂 - 但这是要点。

3 个答案:

答案 0 :(得分:5)

你不能使用静态AAA语法来验证Rhino中的行为,你不得不回到旧式的“重播”来做AFAIK。

我不是犀牛专家,我通常使用Moq,但我认为这是正确的:

var mocks = new MockRepository();
var printer = mocks.DynamicMock<IPrinter>();
using (mocks.Ordered())
{
    printer.Expect(x => x.PrintComment());
    printer.Expect(x => x.PrintSpecial());
    printer.Expect(x => x.PrintComment());
}
printer.Replay();
Script = new Script(printer);

... Execute Test...

printer.VerifyAllExpectations();

答案 1 :(得分:3)

您不应该测试调用哪些订单方法。您应该进行测试以确保因调用Print方法而发生了正确的效果。

但是,如果你真的必须这样做,我认为最好的方法是创建一个模拟IPrinter,它存储调用的顺序函数,以及传递的参数,然后可以在测试中声明。

答案 2 :(得分:0)

您不需要测试编译器。如果你正在进行某种线程,我可以看到它...但在这种情况下,你发布的内容并非如此。

就像你说的那样,你可以创建一个模拟打印机,并测试方法是按顺序调用的,但它是多余的。

如果不调用前置条件(即先前的方法),你可能最好在特定方法中抛出异常,但这暗示需要重构为单个方法。

此外,您可以使用template method模式来确保按顺序调用这些方法,但除非您要使用其他需要使用该顺序的对象,否则它会过度。< / p>