有可能对这种方法进行单元测试吗?

时间:2010-08-06 19:38:43

标签: c# unit-testing

我正在尝试编写单元测试的以下方法:

using StaticClass;           // writen by some one else, have a dll

namespace Test
{
  Class TestClass
   {
      public void DoSomething(string param1)
      {
         List<string> = StaticClass.GetList(param1)

         // sort the list and do other studd here
      }
  }
}

当我不确定如何为DoSomething方法编写测试时,这取决于另一个类中的静态方法。该方法的输出取决于该机器上的数据库,环境和其他一些其他因素。因此,如果两台机器上的数据库不同,则相同的方法会产生不同的结果。我所知道的是GetList返回一些值,该方法可能已经或可能没有被该类的创建者进行单元测试。

我该如何测试这种方法?是否可以这样说,每当调用StaticClass.Getlist方法返回我在程序中创建的自定义List<String>时?我在c#上写测试。

谢谢,

6 个答案:

答案 0 :(得分:5)

具有副作用的方法的静态类型很麻烦。

您有两种选择:

  • 短期:编写一个具有正确签名的GetList方法的接口。接下来编写一个适配器 - 一个实现此接口的类,并在内部委托给StaticClass。将此适配器类型的实例作为ctor arg或方法arg传递到您的类中。在上面调用GetList。您现在可以使用模拟框架来创建模拟对象并将其传递给测试并将其设置为返回固定值。
  • 长期:将StaticClass转换为非静态类。传入(而不是适配器对象);但这需要访问StaticClass的源代码。

答案 1 :(得分:1)

这是以这种方式使用静力学有时不受欢迎的原因之一 - 尽管它们很方便,但它们很难测试。

一种方法是将该类的工作抽象为其他东西。

例如,您可以声明

public interface ISomeonesDllService 
{
    IList<string> GetList(string param1);
}

现在创建一个使用StaticClass的实现:

public class SomeonesDllService : ISomeonesDllService
{
    public IList<string> GetList(string param1)
    {
        return StaticClass.GetList(param1);
    }
}

要使TestClass可测试,可以在类构造函数中为此外部服务注入依赖项:

public class TestClass
{
    ISomeonesDllService dllService;

    public TestClass(ISomeonesDllService dllService)
    {
        this.dllService = dllService;
    }

    public void DoSomething(string param1)
    {
        IList<string> strings = dllService.GetList(param1);
        // do work
    }
}

现在您可以非常轻松地测试DoSomething()方法,因为在测试夹具中,您可以使用TestClass的不同实现来实例化ISomeonesDllService。你可以手工滚动一个只返回静态字符串列表的存根,或者你可以使用一个模拟框架,比如Rhino.Mocks来为你设置(我推荐)。

通过这种方式,您可以将DoSomething()与外部依赖项的工作隔离开来。

答案 2 :(得分:0)

你需要使用Mock对象来测试这种东西。请参阅这篇精彩的文章:http://gamesfromwithin.com/mock-objects-friends-or-foes

基本上你会创建一个模拟与其接口的对象的对象,然后验证你的期望。

答案 3 :(得分:0)

如果我看到这个,这个方法将无法编译。但是如果你想在静态类中测试这个方法,可以单独进行测试。

您班级中的方法不会返回任何内容。如果在系统中只有输入,则不需要实现它。

答案 4 :(得分:0)

您可以为静态类创建非静态包装器,而是使用包装器。

类似

Class StaticClassWrapper {
  public List<string> GetList(string param1) {
    return StaticClass.GetList(param1);
  }
}

然后使用包装器而不是TestClass中的静态类

答案 5 :(得分:0)

使StaticClass成为可以使用Moq,Rhino等进行模拟的依赖项。然后,您可以自由地模拟StaticClass以返回已知的List<string>,或者只是验证它是否通过模拟调用。