单元测试Mock使用 Microsoft Fakes 讲解


本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载。

在编写单元测试时,我们会遇到不同的外部依赖项,大体上可以分为两类:

  • 依赖于接口或抽象类
  • 依赖于具体类

我们将使用 Microsoft Fakes 分别对两种条件下的依赖项进行隔离。

依赖于接口或抽象类

生活不总是那么美好,当然不是所有代码都会遵循控制反转的原则。很多时候,我们仍然需要使用具体类。

比如,在如下的代码中,OrderRepository 中的 Add 方法直接构建一个 EmailSender ,然后调用其 SendEmail 方法来发送邮件。

 1   public class Order
 2   {
 3     public long Id { get; set; }
 4     public override string ToString()
 5     {
 6       return Id.ToString();
 7     }
 8   }
 9 
10   public interface IOrderRepository
11   {
12     Order Add(Order order);
13   }
14 
15   public class EmailSender : IEmailSender
16   {
17     public bool SendEmail(string content)
18     {
19       return true;
20     }
21   }
22 
23   public class OrderRepository : IOrderRepository
24   {
25     public OrderRepository()
26     {
27     }
28 
29     public Order Add(Order order)
30     {
31       IEmailSender emailSender = new EmailSender();
32       emailSender.SendEmail(order.ToString());
33       return order;
34     }
35   }

现在,我们已经没有接口或者抽象类可用于模拟了,所以 Stub 在此种条件下也失去了作用。此时,Shim 上场了。Shim 是运行时方法拦截器,功能更加强大。通过 Shim 我们可以为任意类的方法或属性提供我们自己的实现。

 1     [TestMethod]
 2     public void TestOrderRepositoryWhenAddOrderThenShouldSendEmail()
 3     {
 4       // Arrange
 5       bool isEmailSent = false;
 6 
 7       using (ShimsContext.Create())
 8       {
 9         ShimEmailSender.AllInstances.SendEmailString = (@this, content) =>
10         {
11           isEmailSent = true;
12           return true;
13         };
14 
15         // Act
16         OrderRepository repository = new OrderRepository();
17         Order order = new Order() { Id = 123 };
18         repository.Add(order);
19       }
20 
21       // Assert
22       Assert.IsTrue(isEmailSent);
23     }

使用 Shim 时,需要先为其指定上下文范围,通过 ShimsContext.Create() 来创建。

通常,如果遇到使用 Shim 的情况,则说明代码或许写的有些问题,没有遵循控制反转原则等。

使用 Shim 来控制系统类

  • Isolating Code Under Test with Microsoft Fakes
  • Better Unit Testing with Microsoft Fakes
  • Visual studio 2012 Fakes
  • Using shims to isolate your application from other assemblies for unit testing

本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载。

出处:https://www.cnblogs.com/gaochundong/p/unit_test_with_microsoft_fakes.html