我有一个相当复杂的程序架构,逻辑最少,但传递了很多事件处理程序。我正在制作服务器框架的骨架,并且有以下类:
Core
,它听:
CommHandler
,它听:
CommLayer
,它听:
IServerMock
,我使用模拟框架 (MOQ) 将其删除。
对由事件触发的这种关系进行单元测试的最佳方法是什么?我知道单元测试应该是非常孤立和细化的东西,但我能想到的唯一测试方法是测试整个过程并检查 Core 的最终输出。
我有一个相当复杂的程序架构,逻辑最少,但传递了很多事件处理程序。我正在制作服务器框架的骨架,并且有以下类:
Core
,它听:
CommHandler
,它听:
CommLayer
,它听:
IServerMock
,我使用模拟框架 (MOQ) 将其删除。
对由事件触发的这种关系进行单元测试的最佳方法是什么?我知道单元测试应该是非常孤立和细化的东西,但我能想到的唯一测试方法是测试整个过程并检查 Core 的最终输出。
您需要为每个类进行抽象,因此Core
取决于ICommHandler
非CommHandler
等。依赖项应该通过构造函数提供,这样您就可以轻松地单独测试每个类,因为您可以模拟它的依赖项。
public class Core
{
private ICommHandler commHandler;
public Core(ICommHandler commHandler)
{
this.commHandler = commHandler;
}
}
在您的生产代码中,您可以执行以下操作:
var core = new Core(new CommHandler());
尽管使用 IOC 容器来管理对象的实例化会更好,因为CommHandler
它有自己的依赖关系,但您应该单独研究。
然后在你的单元测试中,你可以这样做:
[Test]
public void TestSomeCommHandlerEvent()
{
var mockCommHandler = new Mock<ICommHandler>();
// set up the mock
var core = new Core(mockCommHandler.Object);
}
这样做可以让您将测试中的 ICommHandler 的实现替换为可以配置其行为的模拟。
听起来您可以模拟事件并检查侦听器是否执行正确的操作(即调用自己的事件)。例如:
// Create objects
var commLayerMock = new Mock<ICommLayer>();
var commHandler = new CommHandler(commLayerMock.Object);
// subscribe to CommHandler event
bool raised = false;
commHandler.OnCommHandlerEvent += delegate { raised = true; };
// Raise CommLayer event, ensure CommHandler event was subsequently raised
commLayerMock.Raise(m => m.OnCommLayerEvent += null, new CommLayerEventArgs());
Assert.True(raised);
您可能希望在每个级别都执行类似的操作,以便您知道如果每个级别之间的交互正常工作,则整个链条将正常工作。