难道一个中间地带存在吗? (单元测试与集成测试) [英] Does a Middle Ground Exist? (Unit Testing vs. Integration Testing)

查看:135
本文介绍了难道一个中间地带存在吗? (单元测试与集成测试)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑存储库模式(或类似)的实现。我会尽量保持示例/图尽可能简洁:

Consider an implementation of the Repository Pattern (or similar). I'll try to keep the example/illustration as succinct as possible:

interface IRepository<T>
{
    void Add(T entity);
}

public class Repository<T> : IRepository<T>
{
    public void Add(T entity)
    {
        // Some logic to add the entity to the repository here.
    }
}

在这个特定的实现,该库是由一个定义接口IRepository有一个方法,它增加了一个实体的存储库,从而使资源库依赖于泛型类型T(也行,库必须可隐式依赖于另一种类型的TDataAccessLayer,因为抽象是库模式的全部要点。这依赖性,然而,目前不容易得到)。在这一点上,从迄今我了解,我有两个选择:单元测试和集成测试

In this particular implementation, the Repository is defined by an interface IRepository to have one method which adds an entity to the repository, thus making Repository dependant upon the generic type T (also, the Repository must be implicitly dependant upon another type TDataAccessLayer, since the abstraction is the entire point of the Repository Pattern. This dependency, however, is not currently readily available). At this point, from what I understand so far, I have two options: Unit Testing and Integration Testing.

在哪里集成测试可以假定有移动更多数量的部分,我宁愿最初单元测试,以作为至少验证基本功能。然而,如果没有建立某种形式的实体属性(通用类型T的),我看不出有什么主张,任何逻辑存储库实现的Add()方法中实际执行的方式。

Where Integration Testing may be assumed to have a greater number of moving parts, I would much rather initially Unit Test in order to as least verify a baseline functionality. However, without creating some sort of "entity" property (of generic type T), I can see no way of asserting that any logic is actually performed within the Add() method of the Repository implementation.

是存在的,也许,一个中间地带某处单元测试和集成测试之间,允许(通过反射或其他方式),以验证执行的特定点已被测试单元内达到了?

Is there, perhaps, a middle ground somewhere between Unit Testing and Integration Testing which allows (through Reflection or some other means) to verify that specific points of execution have been reached within a tested unit?

我已经想出了这个特殊问题唯一的解释就是进一步抽象的数据访问层从资源库,从而在Add()方法不仅接受一个实体参数也有数据访问参数。这似乎对我来说,它可能打败Repository模式的目的,但由于仓库的消费者现在必须了解数据访问层。

The only explanation I've come up with for this particular issue is to further abstract the Data Access Layer from the repository, resulting in the Add() method accepting not only an entity argument but also a Data Access argument. This seems to me like it might defeat the purpose of the Repository Pattern, however, since the consumer of the Repository must now know about the Data Access Layer.

关于请求的例子:

(1)对于单元测试,我不知道像一个存储库实际上可以进行单元测试我目前的测试技术的认识。由于存储库是一个抽象(包装)围绕一个特定的数据访问层,似乎验证的唯一方法将是一个集成测试? (当然,一个库接口可能不会依赖于任何特定DAL,但任何实施库肯定被绑定到特定的DAL执行情况,因此需要能够测试的Add()方法实际执行一些工作)。

(1) And in regard to Unit Testing, I'm not sure something like a Repository could actually be Unit Tested with my understanding of current testing techniques. Because a Repository is an abstraction (wrapper) around a specific Data Access Layer, it seems that the only method of verification would be an Integration Test? (Granted, a Repository Interface may not be tied to any specific DAL, but any implemented Repository must surely be tied to a specific DAL implementation, therefore the need to be able to test that the Add() method actually performs some work).

(2)对于集成测试,测试,据我所知的技术,将验证Add()方法通过实际调用Add执行work()方法(这应该记录添加到存储库),然后检查,看看(在特定的场景或者数据库)中的数据实际添加到库中。这可能是这个样子:

(2) And in regard to Integration Testing, the test, as I understand the technique, would verify the Add() method performing work by actually calling the Add() method (which should add a record to the repository) and then check to see that the data was actually added to the repository (or perhaps database in a specific scenario). This may look something like:

[TestMethod]
public void Add()
{
    Repository<Int32> repository = new Repository<Int32>();
    Int32 testData = 10;

    repository.Add(testData);

    // Intended to illustrate the point succinctly. Perhaps the repository Get() method would not
    // be called (and a DBCommand unrelated to the repository issued instead). However, assuming the
    // Get() method to have been previously verified, this could work.
    Assert.IsTrue(testData == repository.Get(testData));
}



因此,在这种情况下,假定存储库是周围的一些数据库逻辑的包装层,数据库实际上是在测试过程中打两次(插入过程中一次,一旦在检索)。

So, in this instance, assuming the repository is a wrapper around some database logic layer, the database is actually hit twice during the test (once during insert, and once during retrieve).

现在,有什么我可以看到是有用的,将是一个技术用于验证运行时间期间一个特定的执行路径取。一个例子可以是,如果一个非空引用传递中,验证执行路径A被采取,并且如果空引用传递中,验证执行路径B被采取。此外,或许人们可以验证特定LINQ查询是被执行。因此,数据库是没有实际测试中达到(允许原型设计和实施的发展不到位的实际DAL)。

Now, what I could see being useful, would be a technique for verifying that a certain execution path is taken during runtime. An example could be that if a non-null reference is passed in, verify execution path A is taken, and if a null reference is passed in, verify execution path B is taken. Also, perhaps one could verify that particular LINQ query was to be executed. Therefore, the database is never actually hit during the test (allowing prototyping and development of an implementation without any actual DAL in place).

推荐答案

这听起来像你的模式的实现者说明实施的细节,而不是一个模式的要求履行的测试。如果执行的特定点已被测单元内达到没关系,它只有当具体实现者坚持接口的合同事项。这是完全可以接受的测试,以创建用于测试目的的 T 实体,这就是嘲笑是。

It sounds like you're describing the testing of an implementation detail rather than fulfillment of the requirements of a pattern by an implementor of the pattern. It doesn't matter if "specific points of execution" have been reached within the tested unit, it only matters if the concrete implementor upholds the contract of the interface. It's perfectly acceptable for tests to create a T entity for testing purposes, that's what mocks are for.

这篇关于难道一个中间地带存在吗? (单元测试与集成测试)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆