1

我目前正在开发一个更大的 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 而无需以任何方式改变方法?

4

3 回答 3

3

实际上,您可以使用反射来模拟单例。看我的回答:

如何模拟静态单例?

于 2013-08-19T13:27:08.873 回答
2

第一步是确定你想做什么......最重要的是确定你的 SUT(被测对象)

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

我不认为你可以做这样的事情,即使你能找到一种技术方法来做到这一点,也不推荐这样做。相反,您应该使用例如存储库来抽象 DAL 层。像这样的东西:

interface IMyRepository
{
   void Send(Bla bla);
}

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

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

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

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

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

看看以下链接:

你有兴趣为你的代码编写测试是件好事,但由于你没有参加 TDD,这意味着首先编写测试,你编写代码时没有考虑可测试性,结果很简单:编写测试将一个真正的 PITA 并编写它们将需要重构您的代码。

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

于 2012-06-25T21:44:09.990 回答
1

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

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

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

于 2012-06-25T21:40:53.950 回答