作为一个单元测试新手,我一直在读一个测试应该用于一种方法
那么,测试下面的方法DoStuff
的方法是什么?
这是三个单独的测试,每个接口案例都有适当的Setup
吗?
或者,它是Setup
和Returns
的一项测试,更像是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();
}
}
答案 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;它会有所帮助。在这种情况下,你可以在一个简短的句子中描述。