1

在尝试提供可单元测试(使用 Moq)的抽象时,ConcurrentQueue<T>我正在争论是否会失去使用框架ConcurrentQueue<T>实现的好处,这取决于我如何创作抽象。

在以下代码清单中执行一项或另一项的含义是什么:

public abstract class MyMessageQueue1<T> : ConcurrentQueue<T>
{
    public new virtual void Enqueue(T item)
    {
        base.Enqueue(item);
    }
}

public class MyMessageQueue2<T>
{
    private readonly ConcurrentQueue<T> _concurrentQueue = 
        new ConcurrentQueue<T>();

    public virtual void Enqueue(T item)
    {
        _concurrentQueue.Enqueue(item);
    }
}

在第一个实现 ( MyMessageQueue1) 中,我隐藏了任何基类方法,以便在将调用传递给基类之前提供我的实现。

在第二个实现中,我将ConcurrentQueue<T>内部包装起来,并在需要时将调用传递给它。

是否MyMessageQueue2必须手动处理并发,或者因为所有调用都传递给被包装的ConcurrentQueue<T>.

4

2 回答 2

2

在任何一种情况下,您都不必处理并发,因为您所做的只是将调用委托给 ConcurrentQueue,正如@nanda 所述。但是,这将有助于我们了解您包装此类的原因。它对单元测试相当友好,因为它不使用任何外部资源,如文件或数据库。当在你的类中使用时,你可以让它做它的工作,而不是测试你自己的使用 ConcurrentQueue 的功能。

如果您尝试包装它是因为您想验证您的方法是否以所需的方式使用它,那么您可能专注于测试方法的实现而不是方法的行为。这在某些情况下可能有用,但您必须意识到这一事实,这不是一种常见的做法。

在编写这样的包装器时,您会丢失一件事。因为包装器具有虚拟方法以便它们可以被模拟,所以不能内联方法并且会损失一些性能。ConcurrentQueue 是苗条和快速的类,这实际上可能是一个问题。

于 2012-11-05T10:43:46.937 回答
1

如果包装器所做的只是委托给 ConcurrentQueue,并且包装器没有自己的成员来保护并发访问,那么您的包装器就无需为并发做任何事情。

但是你会在这个瘦包装器上进行什么单元测试呢?

于 2012-11-02T12:04:20.327 回答