是否应该在包装的代码之外测试包装器?

时间:2017-07-19 16:25:21

标签: c# unit-testing

单元测试是否应该测试方法,方法本身或两者的包装? 这是我的意思的一个例子:

public static class Helper
{
  public static bool DoAThing() {
  //do stuff...
  }
}

[TestClass]
public class HelperTests
{
   [TestMethod]
   public void TestDoAThing()
   {
      Assert.AreEqual(true, Helpers.DoAThing());
   }
}

public class APIMethodsController : ApiController
{
    public bool DoAThingWrapper()
    {
        return Helpers.DoAThing();
    }
}

除了TestDoAThing()之外,还应该对DoAThingWrapper()进行测试吗?

我倾向于认为对于这样一个简单的情况,应该只有TestDoAThing()。但是在为DoAThingWrapper()添加测试之前,包装器中应该有多大的复杂性?

1 个答案:

答案 0 :(得分:3)

  

单元应该测试方法的包装器,方法本身,还是   既?

单元测试应该测试您正在测试的类型的公共接口。如果两种方法都是公开的,那么您应该测试它们。否则,只测试公共包装器。

请注意,您将DoAThing()定义为静态类的实例方法,这在C#中是不允许的。您也将其称为APIMethodsControllerApiController类的实例方法,尽管它在Helper类中定义。

虽然有一些方法可以对依赖于静态的代码进行单元测试(例如TypeMock或Moles),但我建议您依赖于抽象。这将使您的代码易于通过模拟其依赖性进行单元测试。例如。而不是使用很难使测试所需的返回值的Helper.DoAThing(),您可以创建一个调用静态成员的包装器:

public class HelperWrapper : IHelper
{
    public bool DoAThing() => Helper.DoAThing();
}

现在您可以轻松地模拟IHelper并测试使用它的装饰器,以确保调用依赖项DoAThing。我对ConfigurationManager类使用相同的技术。

var helper = new Mock<IHelper>();
helper.Setup(h => h.DoAThing()).Returns(false);
var controller = new APIMethodsController(helper.Object); // inject dependency
var result = controller.DoAThingWrapper();
result.Should().BeFalse(); // ensure you pass through value from helper