我对测试事件调用的简洁,优选流畅的方式感兴趣。我已经看到了一些关于相关概念(尤其是Moq)的例子,但还没有完全实现。
例如,我相信我应该能够实现这样的目标,但只有一两个衬管用于测试:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace EventTest
{
public class TestClient
{
public event Action<string> Output;
public bool Speak(string message)
{
if (Output != null)
{
Output(message);
}
return true;
}
}
[TestClass]
public class BasicActionTests
{
private TestClient Client;
[TestInitialize]
public void Initialize()
{
Client = new TestClient();
}
[TestMethod]
public void Speak()
{
const string message = "she sells sea shells by the sea shore - booyakasha!";
System.Action<string> outDel = (output) =>
{
Assert.AreEqual(message, output);
};
Client.Output += outDel;
try
{
bool success = Client.Speak(message);
Assert.IsTrue(success, "Tongue Tied");
}
finally
{
Client.Output -= outDel;
}
}
}
}
我想在这里保留的关键是,在测试中注册和取消注册事件,无论失败,因为对象是在TestInitialize中创建的。 (我理解并同意理想情况下我们可以在没有它的情况下测试它作为一个干净的单元测试,但请让我们假设在这里需要进行集成测试。)
理想情况下,我希望能够写出类似的内容:
Assert.IsTrue(()=>Client.Speak(message)).VerifyEvent(obj => obj.Output, (msg) => Assert.AreEqual(message, msg));
其中XXX可以是模拟,甚至只是一个Assert扩展。
我见过的最接近的例子是INCPTracer,虽然它并不完全存在(说实话,我宁愿不将它包含在这个单一用例中,但我不介意包含Moq,因为我在其他地方大量使用它,或者另一个提供其他测试功能的“广泛使用的”框架/ lib。)