嘲弄和单身

时间:2012-06-25 21:22:20

标签: c# testing mocking

我目前正在开发一个更大的C#-Project。我写了几个连接到数据库层的类,现在必须测试它们。使用的测试框架是Visual Studio Ultimate。我已经获得了Mock-layer用于测试,但是我不确定如何使用它。

基本上我的方法是这样的:

public static void bla()
{
//This is a multithreaded singleton
Connection con = Connection.Instance;

//This raises a lot of Events 
con.SomeConnection.Send(new GetBla()); 
}

MockLayer基本上是ConnectionMock并将其所有方法实现为模拟。有没有办法让con成为Mock而不以任何方式改变方法?

3 个答案:

答案 0 :(得分:3)

实际上你可以使用反射模拟单身人士。请参阅我的回答:

How to Mock a Static Singleton?

答案 1 :(得分:2)

第一步是确定你想做什么......最重要的是确定你的SUT(受试者)

  

有没有办法让con成为Mock而不以任何方式改变方法?

我认为你不能做那样的事情,即使你能找到一种技术方法,也不建议这样做。相反,您应该使用存储库来抽象DAL层。像这样:

interface IMyRepository
{
   void Send(Bla bla);
}

现在您可以在类中使用DI来注入此接口的引用。当你想编写单元测试时,你应该创建一个界面模拟。

为了轻松创建模拟,我可以推荐以下工具:

无论如何,在您的情况下,测试代码而不更改代码的唯一方法是将连接字符串更改为虚拟数据库,然后运行集成测试

遗憾的是,我必须告诉您,您的代码不是测试友好的,您应该重构代码以删除静态成员。

我可以告诉您的最佳提示是:阅读有关编写干净的测试友好代码的指南。

请看以下链接:

您有兴趣为代码编写测试,但由于您没有使用TDD,这意味着首先编写测试,因此您编写的代码没有可测试性,结果很简单:写作测试将是一个真正的PITA,编写它们将需要重构您的代码。

我知道您不想重构代码,因为您不想破坏现有功能,这是从一开始编写测试的最大好处之一,您将能够重构代码并运行测试确保你没有破坏任何东西

答案 2 :(得分:1)

总之,不,没有办法。这是使用静态类和单例对象的最大缺点之一。您已经定义了一个规则,即只能存在一个Connection对象,并且它始终必须是您指定的确切实例。创建模拟并试图让所有代码使用它将违反该规则。

换句话说,为了模拟对象,您必须能够创建另一个实例并将您的实例替换为预期的实例。静态类(和单例)明确地阻止了这种可能性。

更好的选择是使用依赖注入,以便您的“预期”Connection类始终在真实环境中注册,并且您的模拟总是在单元测试中注册。