2010-08-06 33 views
1

我有以下的方法,我想写一个单元测试:单元测试这种方法有可能吗?

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#的测试。

谢谢,

回答

5

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

你有两个选择:

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

好吧。记住,OP,你试图测试你的方法,而不是'StaticClass.GetList()'。你的方法依赖于GetList()的签名(接受一个字符串,返回一个'List ')(think接口),而不是该签名的特定实现(StaticClass.GetList())。 – 2010-08-06 19:54:32

0

如果我看到这个权利,这个方法不会编译。但是如果你想在静态类中测试这个方法,可以单独测试。

你的类中的方法不返回任何东西。如果在系统中只有输入,你不需要实现它。

0

您可以为静态类创建非静态包装,并使用包装来代替。

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

,然后你使用包装,而不是静态类在你的TestClass

0

让StaticClass,您可以用起订量,犀牛等嘲笑一个扶养你就可以自由要么模拟出StaticClass返回一个已知的List<string>或者只是验证它通过模拟被调用。

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()方法,因为在您的测试夹具中,您可以使用ISomeonesDllService的不同实现实例化TestClass。你可以手动推出一个只返回静态字符串列表的存根,或者你可以使用一个模拟框架,比如Rhino.Mocks为你设置(我推荐)。

通过这种方式,您可以将DoSomething()与外部依赖关系的运作隔离。