简体   繁体   English

如何在NUnit中测试此视图模型的异步行为?

[英]How to test asynchronous behavior of this view model in NUnit?

My view model has a public method void StartBroadcastingAndDiscovery() . 我的视图模型有一个公共方法void StartBroadcastingAndDiscovery() This triggers two private async methods Task StartBroadcasting() and Task StartDiscovering() . 这将触发两个私有异步方法Task StartBroadcasting()Task StartDiscovering() Both of these private methods are (endless) while loops like this: 这两个私有方法都是(无尽的)while循环,如下所示:

while(!ct.IsCancellationRequested)
{
  var discovered = await this.networkService.Discover();
  this.DiscoveredPeers.Add(discovered);
  await Task.Delay(1000);
}

The idea is that the async method used for discovery is polling the network service regularly. 这个想法是,用于发现的异步方法正在定期轮询网络服务。 The network service is injected: 网络服务被注入:

this.networkService = ServiceContainer.Resolve<INetworkService> ();

The user of the model can get a list of discovered peers. 模型的用户可以获取已发现对等项的列表。 The list can change over time as peers appear or disappear from the network. 随着同伴出现或从网络中消失,该列表可能会随着时间变化。 At some point, the user calls void StopBroadcastingAndDiscovering(). 在某个时候,用户调用void StopBroadcastingAndDiscovering().

In order to test my view model I have created a mockup network service that will "discover" three different peers. 为了测试我的视图模型,我创建了一个样机网络服务,该服务将“发现”三个不同的对等点。 First request returns first peer, then the second, then the third and then the first again and so on. 第一个请求返回第一个对等体,然后返回第二个对等体,然后再返回第三个对等体,依此类推。

My problem is now: how do I actually run the test? 现在的问题是:我该如何实际运行测试? What can I test here? 我可以在这里测试什么? I would like to see that the list of discovered peers contains three items after 3 seconds but I don't want to hardcode the 3 secs delay. 我希望看到3秒钟后发现的对等方列表包含三个项目,但我不想对3秒钟的延迟进行硬编码。

The simplest solution would be to refactor Task.Delay to a separate, protected method inside your class like this: 最简单的解决方案是将Task.Delay重构为类内部一个受保护的单独方法,如下所示:

protected Task Wait()
{
    return Task.Delay(1000);
}

Then inside your unit tests, you inherit from your system under test and override the Wait method: 然后在单元测试中,您从被测系统继承并重写Wait方法:

protected override Task Wait()
{
   return Task.FromResult(true);
}

This way, your unit tests will call the overridden version of Wait that returns immediately. 这样,您的单元测试将调用立即返回的重写的Wait版本。 This skips the one second wait and makes your unit tests a lot faster and easier to control. 这样可以跳过一秒钟的等待,使您的单元测试更快,更容易控制。

Extracting to a protected method is called creating a seam. 提取到受保护的方法称为创建接缝。 You can also create seams by using interfaces and dependency injection but that looks like overkill to me for this situation. 您还可以通过使用接口和依赖项注入来创建接缝,但是对于这种情况,这对我来说似乎有些过头了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM