Design patterns 服务中的模拟存储库
我有一个服务,我希望测试不使用“真实”存储库,而是使用模拟存储库。 主程序Design patterns 服务中的模拟存储库,design-patterns,moq,Design Patterns,Moq,我有一个服务,我希望测试不使用“真实”存储库,而是使用模拟存储库。 主程序 ServiceManager service = new ServiceManager(); Customer c = new Customer(); //set customer properties service.Save(c); 服务 public class ServiceManager { public bool Save(Customer customer) { Repos
ServiceManager service = new ServiceManager();
Customer c = new Customer();
//set customer properties
service.Save(c);
服务
public class ServiceManager
{
public bool Save(Customer customer)
{
Repository rep = new Repository();
bool res = rep.Save((customer));
return res;
}
}
在测试中,我不想真正拯救客户。
使用mock,我可以创建存储库
var rep = new Mock<Repository>();
rep.Setup(x => x.Save(customer)).Returns(true);
在本例中,在测试中,我使用setRepository保存模拟。
通常采用的最佳解决方案是什么
如果可能,我不想创建像新ServiceManager(存储库)这样的服务
如果这是一项绝对要求,那么您需要使用像Fakes/Moles
这样的重型工具将moled存储库损坏到您的ServiceManager
SUT中
但是,由于它被标记为moq
,如果您确实解耦了依赖项(例如通过Setter构造函数注入),那么您可以单独进行单元测试和Mock
。对于可测试代码来说,这是一个很小的开销
public class ServiceManager
{
private readonly Repository _repository;
public ServiceManager(Repository repository)
{
_repository = repository;
}
public bool Save(Customer customer)
{
bool res = _repository.Save((customer));
return res;
}
}
您的单元测试现在将能够创建ServiceManager
(SUT)并注入模拟存储库
更好的做法是将存储库抽象为一个接口,IRepository
,然后将ServiceManager
对repository
的依赖性降低到一个接口。然后,您的moq回购是var rep=new Mock()
并且依赖关系变为私有只读IRepository\u存储库
经典的方法是使用控制反转(这意味着ServiceManager
不再控制创建存储库
),通常通过依赖项注入实现(这意味着依赖项存储库
被“注入”到服务管理器
)
你似乎已经知道了,自从你写了 如果可能,我不想创建像新ServiceManager(存储库)这样的服务 要实现这一点,可以在
ServiceManager
的构造函数中使用可选参数,如:
public class ServiceManager
{
private readonly IRepository rep;
public ServiceManager(IRepository rep=null)
{
_rep = rep ?? new Repository();
}
public bool Save(Customer customer)
{
bool res = _rep.Save((customer));
return res;
}
}
只需在应用程序中使用newservicemanager()
,并在测试中使用newservicemanager(repositoryMock)
但是,如果您使用IOC容器(例如StructureMap),注入依赖项非常简单:您可以将对象的创建留给IOC容器,并使您的
ServiceManager
和其他类在手动创建依赖类的实例时保持“干净”
public class ServiceManager
{
private readonly IRepository rep;
public ServiceManager(IRepository rep=null)
{
_rep = rep ?? new Repository();
}
public bool Save(Customer customer)
{
bool res = _rep.Save((customer));
return res;
}
}