如果您正在测试依赖于UserRepository 的UserDomain,那么您不是在对接口进行编码,而是对具体/实现进行编码。这反过来又将两者结合在一起。耦合代码意味着难以对代码进行单元测试,因为没有UserRepository 就没有测试UserDomain。
在你的例子中,你可能有这样的东西:
public class UserDomain
{
public object GetAllUsers()
{
UserRepository repo = new UserRepository();
var results = repo.GetAllUsers();
// do some stuff like transforming it
return null;
}
}
public class UserRepository
{
public object GetAllUsers()
{
return null; // implementation
}
}
用这种方法编码的问题是你不能真正“单元测试”UserDomain,因为它依赖于UserRepository。为了完成真正的单元测试,您的作品必须不依赖于实现,而是依赖于接口之类的抽象。
要完成单元测试,您的类可以看起来更像:
public class UserDomain
{
private readonly IUserRepository _iUserRepository;
public UserDomain(IUserRepository iUserRepository)
{
_iUserRepository = iUserRepository;
}
public object GetAllUsers()
{
var results = _iUserRepository.GetAllUsers();
// do some stuff like transforming it
return null;
}
}
public interface IUserRepository
{
object GetAllUsers();
}
public class UserRepository : IUserRepository
{
public object GetAllUsers()
{
return null;
}
}
请注意,一旦您了解了您所看到的内容,这里并没有真正改变很多。我们创建了一个新接口IUserRepository,UserRepository 现在实现了它。 UserDomain 也被更新为而不是新的特定实现 (UserRepository),采用 IUserRepository 的实例。
这意味着一些事情,UserDomain 不再直接依赖于 UserRepository,它现在依赖于抽象 IUserRepository,它可以很容易地被模拟、存根或伪造,以便为测试目的。
在构造函数中传入接口实现的概念称为dependency injection。构造函数注入是完成依赖注入的一种方法,但也有其他方法。它的基本思想是,如果一个类有依赖关系,这些依赖关系应该在接口/合同上,而不是文字实现上。
综上所述,集成测试是在UserDomain 范围内使用UserRepository 等实际实现的测试,而不是您的存根、模拟、伪造IUserRepository。