c# - 用最小起订量测试这个的正确方法

标签 c# unit-testing moq

我为我需要的优先级队列编写了一个实现,现在我想测试它。我决定使用最小起订量,因为我已经在工作中使用过 rhino mocks 并且想尝试一些新的/可能更简单的东西。

我的 PriorityQueue 的界面非常简单:

public interface IPriorityQueue<TKey, TValue>  where TKey : IComparable
{
    void Enqueue(TKey priority, TValue value);
    bool IsEmpty();
    TValue Peek();
    TValue Dequeue();
}

我去写我的第一个测试,测试Enqueue方法。这是它的实现:

public void Enqueue(TKey priority, TValue value)
{
    if (priority == null) { throw new ArgumentNullException("priority"); }

    if (_queue.ContainsKey(priority))
    {
        // queue contains key, therefore just add value to existing key's list
        _queue[priority].Add(value);
    }

    // otherwise just add pair
    else
    {
        _queue.Add(priority, new List<TValue>() { value });
    }
}

我写的第一个单元测试是测试键是否为空,它应该抛出一个参数为空的异常。

[TestMethod]
public void EnqueueNullKey_ThrowsArgumentNullException()
{
    /* Arrange */
    var mock = new Mock<IPriorityQueue<string, IMessage>>();

    // string implements the IComparable interface, and is nullable.
    mock
        .Setup(x => x.Enqueue(null, It.IsAny<IMessage>()))
        .Throws<ArgumentNullException>();

    /* Assert */
    mock.VerifyAll();   
}

所以我现在意识到,我的方法 Enqueue 永远不会被调用,因为我正在实例化我的接口(interface)实例,而不是实现。那么问题来了,如果我应该使用我的接口(interface)进行测试(至少这是我在观看 Roy Osherove 的 TDD - Understanding Mock Objects 视频后得到的印象)我该如何测试我的实现?

我是否误解了使用接口(interface)进行测试的建议?

在视频中,他在他正在编写的测试中创建了一个类,并用它来进行测试。我看不出这将如何帮助我测试 PriorityQueue 的实现(特别是 Enqueue 方法)。

感谢堆栈溢出!

编辑:这是我提出的以下(丑陋的)工作测试。我对此非常不满意,感觉太原始了。任何人都可以建议更好的方法吗?从下面的回复来看,这个单元测试似乎完全不需要框架。

然而,这里是:

[TestMethod]
public void EnqueueNullKey_ThrowsArgumentNullException()
{
    /* Arrange */
    var pq = new PriorityQueue<string, IMessage>();

    try
    {
        pq.Enqueue(null, null);
    }
    catch(ArgumentNullException)
    {
        Assert.IsTrue(true);
        return;
    }

    // failure condition if we don't catch the exception
    Assert.IsTrue(false);   
}

最佳答案

我觉得有些误会。

如果您的测试对象具有定义为接口(interface)的依赖项,您将模拟它们以便能够测试您的单元。

在您的情况下,您没有需要替换以进行测试的依赖项。因为您想测试您的 实现,所以没有必要模拟它。恕我直言,没有必要测试 BCL 的现有类。

测试(Nunit)测试可能看起来像这样(未经测试)

[TestMethod]
public void EnqueueNullKey_ThrowsArgumentNullException()
{
   var queue = new YourPriorityQueue<string, IMessage>();
   var message = new SomeFooMessage(); // or use a mock for this

   Assert.Throws(typeof(ArgumentNullException), () => queue.Enqueue(null, message);
}

关于c# - 用最小起订量测试这个的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8830658/

相关文章:

c# - 延迟异步方法的最小起订量返回不延迟

c# - 使用 Moq 查看是否使用值调用了方法

c# - 如果其中存在一个单词,如何删除整行?

c# - 仅返回字符串中的数字 0-9

python - 如何将 fixture 作为参数传递给另一个 fixture

python - py.test : Mocking a datetime object that is constantly changing

c# - ExpectedException 属性用法

c# - "aapt.exe"为 Android 项目构建 Mono 时退出代码 1

c# - Azure 图形 API 不适用于上一页请求 (&previous-page=true)

asp.net-mvc - 如何使用 Moq 模拟 ActionExecutingContext?