Unit testing 单元测试在什么时候变成集成测试?

Unit testing 单元测试在什么时候变成集成测试?,unit-testing,integration-testing,Unit Testing,Integration Testing,单元测试涉及测试应用程序的最小单元。因此,可以针对UserRepository编写一个单元测试来测试GetAllUsers()方法 还可以针对UserDomain编写单元测试,以测试GetAllUsers()方法。既然UserDomain调用了UserRepository,UserDomain测试会被视为集成测试吗 或者,如果存在一个将API提供到后端的服务层,那么UserDomain测试会被视为单元测试吗?如果您正在测试依赖于UserRepository的UserDomain,那么您不是在对接

单元测试涉及测试应用程序的最小单元。因此,可以针对UserRepository编写一个单元测试来测试GetAllUsers()方法

还可以针对UserDomain编写单元测试,以测试GetAllUsers()方法。既然UserDomain调用了UserRepository,UserDomain测试会被视为集成测试吗


或者,如果存在一个将API提供到后端的服务层,那么UserDomain测试会被视为单元测试吗?

如果您正在测试依赖于
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
,它可以很容易地模仿、存根或伪造,以便为测试目的提供测试功能

在构造函数中传递接口实现的概念称为。构造函数注入是实现依赖项注入的一种方法,但也有其他方法。它的基本思想是,如果一个类有依赖项,那么这些依赖项应该在接口/契约上,而不是在文本实现上


综上所述,集成测试是一种在
UserDomain
范围内使用实际实现(如
UserRepository
)的测试,而不是使用存根、模拟、伪造的
IUserRepository

如果它涉及两个或更多单元,则是一种集成测试。根据您的经验,很多开发人员在域层创建单元测试,在服务层创建集成测试吗?基本上,由于回报递减,他们跳过了回购层的单元测试?专注于代码内部逻辑的单元测试;数据访问层可能足够精简,只能通过集成测试来实现