【问题标题】:How to moq a static class with a static method (UnitOfWork case)?如何使用静态方法(UnitOfWork 案例)对静态类进行起订量?
【发布时间】:2011-05-16 00:12:04
【问题描述】:

我有这些课程:

public static class UnitOfWorkSS 
{
  public static IUnitOfWork Begin()
  {
    return IoC.Resolve<IUnitOfWork>();
  }
}

public class PostService
{
  using (IUnitOfWork unitOfWork = UnitOfWorkSS.Begin())
  {
    //don't forget to sanitize html content
    htmlContent = _htmlSanitizer.Sanitize(htmlContent);

    IPost post = _factory.CreatePost(byUser, title, htmlContent);                    

    _postRepository.Add(post);

    unitOfWork.Commit();
  }
}

如何模拟 UnitOfWorkSSunitOfWork 类?

【问题讨论】:

    标签: c# .net mocking moq


    【解决方案1】:

    据我所知,您不能模拟静态类或方法。

    【讨论】:

    • 是的,我意识到了这一点。但问题是我需要伪造该功能,有没有办法做到这一点?
    • 据我所知,您必须将工作单元重写为非静态的。
    【解决方案2】:

    模拟 IUnitOfWork 并将其注册到您的容器中,以便可以解析它。

    【讨论】:

      【解决方案3】:

      看起来您对 Begin() 的调用唯一要做的就是返回您为该特定接口配置的类:IUnitOfWork

      您真的只需要确保您对 Begin() 的调用返回一个模拟实现 IUnitOfWork

      您可以通过以下两种方式之一:

      选项一 - 重构 UnitOfWorkSS 以便您可以设置要返回的 IUnitOfWork 实例

      public static class UnitOfWorkSS  
      {
          private static IUnitOfWork _unitOfWork;
          public static IUnitOfWork UnitOfWork
          {
              set { _unitOfWork = value; }
              private get{ _unitOfWork ?? (_unitOfWork = IoC.Resolve<IUnitOfWork>()); }
          }
      
          public static IUnitOfWork Begin()  
          {  
              return UnitOfWork;
          }  
      }  
      
      [TestMethod]
      public void DoStuff()
      {
          var mockUnitOfWork = new Mock<IUnitOfWork>();
          UnitOfWorkSS.UnitOfWork = mockUnitOfWork.Object;
      
          //Do some setup and verify
      }
      

      选项二 - 只需将 IUnitOfWork 的模拟实例注册到您的 IoC 容器

      private Mock<IUnitOfWork> _mockUnitOfWork;
      
      [TestInitialize]
      public void Init()
      {
          _mockUnitOfWork = new Mock<IUnitOfWork>();
      
          //Making a lot of assumptions about your IoC here...
          IoC.Register<IUnitOfWork>(_mockUnitOfWork.Object);
      }
      
      [TestMethod]
      public void DoStuff()
      {
          _mockUnitOfWork.Setup( ... );
      
          //Do some verification
      }
      

      【讨论】:

      • 选项 2 对我来说似乎更好,因为选项 1 将状态引入静态类只是为了使其可测试 - 但也许这就是 OP 正在寻找的全部。
      【解决方案4】:

      我意识到这是一个非常古老的问题,但万一有人在这里结束......

      最好的解决方案是像其他答案所说的那样进行设计更改。但是,如果这不可行,您可以使用 Microsoft Fakes(它取代了 Moles),或者,如果您不想依赖 Visual Studio,那么有一个名为 Smocks 的库可以提供帮助。

      https://github.com/vanderkleij/Smocks

      【讨论】:

        猜你喜欢
        • 2014-06-12
        • 2011-06-25
        • 1970-01-01
        • 2023-04-02
        • 2013-06-30
        相关资源
        最近更新 更多