11
votes

I have these classes:

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();
  }
}

How can I mock the classes UnitOfWorkSS and unitOfWork?

4

4 Answers

9
votes

It looks like the only thing you are doing with the call to Begin() is returning your configured class for that particular interface: IUnitOfWork

You really just need to make sure that your call to Begin() returns a mock implementation of IUnitOfWork

One of two ways you can do this:

Option One - Refactor UnitOfWorkSS so that you can set the instance of IUnitOfWork to be returned

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
}

Option Two - Simply register a mock instance of IUnitOfWork with your IoC Container

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
votes

Mock the IUnitOfWork and register it into your container so that it can be resolved.

1
votes

As far as I know, you cannot mock static classes or methods.

1
votes

I realize this is a very old question, but in case someone ends up here...

The best solution is a design change like the other answers say. However, if that's not possible, you can either use Microsoft Fakes (which replaced Moles) or, if you'd rather not depend on Visual Studio, there is a library called Smocks that can help.

https://github.com/vanderkleij/Smocks