我有这些课程:
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();
}
}
我怎么能模拟这些课程 UnitOfWorkSS
和 unitOfWork
?
看起来你通过调用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
}
看起来你通过调用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
}
模拟IUnitOfWork并将其注册到容器中,以便可以解决它。
我意识到这是一个非常古老的问题,但万一有人在这里结束......
最好的解决方案是像其他答案所说的设计变更。但是,如果这不可能,您可以使用Microsoft Fakes(替换Moles),或者,如果您不依赖于Visual Studio,则可以使用名为Smocks的库来提供帮助。
https://github.com/vanderkleij/Smocks