单元测试具有多个接口调用的方法

时间:2016-06-08 21:02:27

标签: unit-testing moq xunit

作为一个单元测试新手,我一直在读一个测试应该用于一种方法 那么,测试下面的方法DoStuff的方法是什么?

这是三个单独的测试,每个接口案例都有适当的Setup吗? 或者,它是SetupReturns的一项测试,更像是Strict行为吗?

public class MainClass
{
    IFoo myFoo;
    IBar myBar;
    IBaz myBaz;

    public MainClass(IFoo foo, IBar bar, IBaz baz) {
        this.myFoo= foo;
        this.myBar= bar;
        this.myBaz= baz;
    }

    public void DoStuff(string myParam) {
        var fooResult = myFoo.doFoo(myParam);
        myBar.doBar(fooResult);
        myBaz.doBaz();
    }
}

2 个答案:

答案 0 :(得分:1)

  

我一直在读一个测试应该用于一种方法

事实并非如此。您可以为方法进行多次单元测试。

在" DoStuff"中,除了调用myFoo和myBar之外,没有真正的行为/逻辑。

没有太多的价值你得到单位测试这个例行的IMO。 非常类似于编排例程的服务调用。

答案 1 :(得分:1)

我冒昧地使用NSubstitute而不是moq,但你可以自己找出用moq做的方法。我也将使用AutoFixture.Xunit2因为它很棒。

private MainClass _target;
private IFoo _foo = Substitue.For<IFoo>();
private IBar _bar = Substitute.For<IBar>();
private IBaz _baz = Substitute.For<IBaz>();

public MainClassTest()
{
    _target = new MainClass(_foo, _bar, _baz);
}

[Theory, AutoData]
public void DoStuff_Delegates_To_Foo(string myParam)
{
    _target.DoStuff(myParam);
    _foo.Received.DoFoo(Arg.Is(myParam));
}

[Theory, AutoData]
public void DoStuff_Calls_Bar_With_Result_From_Foo(string myParam, object fooResult)
{
    _foo.DoFoo(Arg.Is(myParam)).Returns(fooResult);

    _target.DoStuff(myParam);

    _bar.Received().DoBar(Arg.Is(fooResult));
}

[Theory, AutoData]
public void DoStuff_Calls_Baz_After_Foo_And_Bar(string myParam)
{
    _target.DoStuff(myParam);

    Received.InOrder(() => 
    {
        _foo.DoFoo(Arg.Any<string>());
        _bar.DoBar(Arg.Any<object>());
        _baz.DoBaz();
    }
}

我们的想法是为您想要了解的DoStuff方法提供一种测试方法。以上只是示例,如果您愿意,您也可以在一次测试中全部编写。这里面临的挑战是如何对您测试的内容进行详细描述(因此想象一下您的测试命名并且您的同事实现了它),无论如何,下面是一个测试方法的示例,它测试所有内容。

[Theory, AutoData]
public void DoStuff_Does_What_It_Is_Supposed_To_Do(string myParam, object fooResult)
{
    _foo.DoFoo(Arg.Is(myParam)).Returns(fooResult);

    _target.DoStuff(myParam);

    Received.InOrder(() => 
    {
        _foo.DoFoo(Arg.Is(myParam));
        _bar.DoBar(Arg.Is(fooResult));
        _baz.DoBaz();
    }
}

所以回答你的问题,归结为命名。如果你能用一个简短的句子描述测试,那就继续吧。您可能听说过每种测试方法都应该测试一件事而且只测试一件事,如果您想到&#34;事情&#34;它会有所帮助。在这种情况下,你可以在一个简短的句子中描述。