今天的文章内容是参考於 Testing C# Async Code with NUnit and NSubstitute,其目的在於想了解如何程序码带有非同步的方法时,则测试是否有需要改写或注意的地方。大概简述非同步方法的概念与语法,非同步方法是指执行某特定任务,无需等该特定任务完成就去执行其他的任务(比如泡咖啡要等咖啡出来的时候做早餐),而我们采用的是 Task-Based 的方式撰写,其中会用到 async 与 await,详细内容可参见async 与 await,仅节录其中一段撰写的语法:
static async Task<string> MyDownloadPageAsync(string url)
{
using (var webClient = new WebClient())
{
Task<string> task = webClient.DownloadStringTaskAsync(url);
string content = await task;
return content;
}
}
因此,从参考影片中提供了一个故事情节,其目的是我们取 Cache 中指定 Key 的数值,而 Cache 未有该 Key 的数值或点击超过两次,则会从 Storage 取得最新的值。而 IStorage 提供了两只 Task 方法:Save 与 Load,分别作为储存与载入,程序码如下:
public class DemoCache
{
private readonly IStorage Storage;
private readonly Dictionary<string, int> Hits
= new Dictionary<string, int>();
private readonly Dictionary<string, string> Cache
= new Dictionary<string, string>();
public DemoCache(IStorage inStorage) {
Storage = inStorage;
}
public async Task<string> Get(string key)
{
if (!Hits.ContainsKey(key) || Hits[key] >= 2)
{
string value = await Storage.Load(key);
Cache[key] = value;
Hits[key] = 1;
return value;
}
else
{
Hits[key]++;
return Cache[key];
}
}
}
public interface IStorage
{
Task Save(string key, string value);
Task<string> Load(string key);
}
於是乎,我们就可以开始撰写测试码,而测试的情境要考量数种情况,分别如下:
[Test]
public async Task SingleGet()
{
// Arrange
var storage = Substitute.For<IStorage>();
storage.Load("key").Returns("value1");
var cache = new DemoCache(storage);
// Act
var result = await cache.Get("key");
// Assert
await storage.Received(1).Load("key");
Assert.AreEqual(result, "value1");
}
[Test]
public async Task MultipleGets_WithDifferentKeys()
{
// Arrange
var storage = Substitute.For<IStorage>();
var cache = new DemoCache(storage);
// Act
await cache.Get("key1");
await cache.Get("key2");
// Assert
await storage.Received(1).Load("key1");
await storage.Received(1).Load("key2");
}
[Test]
public async Task MultipleGets_WithSametKeys()
{
// Arrange
var storage = Substitute.For<IStorage>();
var cache = new DemoCache(storage);
// Act
await cache.Get("key1");
await cache.Get("key1");
await cache.Get("key1");
// Assert
await storage.Received(2).Load("key1");
}
後面还有其他的测试情况,会在明天叙述。
<<: [Day10] Hold Shift to Check Multiple Checkboxes
>>: 【把玩Azure DevOps】Day13 Pipeline与Artifacts应用:Build nuget package上传到Private nuget
从头到尾硬干一个网站是非常费功费时的事情,为了节省开发时间就会尽量引用现成的套件,随着引用的套件越来...
Cloud Monitor 如果使用了GCP平台,要如何捕捉以及监控错误,我想大概多半会使用Clo...
制作目标 完成系统 发现问题 Icebear将readline的终止程序放在回圈以前,造成输入料理名...
27 - Concern 最後整理的方式再来讲到 Rails 提供功能,主要目的在把相同逻辑 cod...
在开始使用 React 之前,先来回想一下刚学习原生 JS 的时候,我们是怎麽在页面产生 DOM N...