如何使用静态方法(UnitOfWork case)moq静态类?

时间:2010-11-26 03:51:23

标签: c# .net mocking moq

我有这些课程:

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

4 个答案:

答案 0 :(得分:9)

看起来你对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
}

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

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
}

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

最好的解决方案是设计变更,就像其他答案所说的那样。但是,如果不可能,您可以使用Microsoft Fakes(替换Moles),或者,如果您不依赖于Visual Studio,则可以使用名为Smocks的库来提供帮助。

https://github.com/vanderkleij/Smocks