news 2026/9/27 21:33:15

使用C#编写微信小程序(3)单元测试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用C#编写微信小程序(3)单元测试

单元测试使用C#的单元测试,一切与C#无关的平台统一使用接口,通过依赖注入和mock使用

案例: 微信小程序Storage单元测试

using System.Text.Json; using System.Threading.Tasks; using TsRoslyn.Core.Api; using TsRoslyn.Razor.Core; using XieYun.Application.Interfaces; namespace XieYun.Application.Services; // 微信api抽象为IWxApi。隔离js和C# public class LocalStore<T>(IWxApi wxApi) : IStore<T> where T : class { private bool IsInitialized { get; set; } private T? Data { get; set; } public async Task<T?> GetAsync() { if (IsInitialized) return Data; var storeDataString = await wxApi.GetStorageAsync(typeof(T).ToString()); T? result = null; if (storeDataString is not null) { result = JsonSerializer.Deserialize<T>(storeDataString); } Data = result; IsInitialized = true; return result; } public Task SetAsync(T value) { Data = value; IsInitialized = true; return wxApi.SetStorageAsync(typeof(T).ToString(), JsonSerializer.Serialize(value)); } }

接下来使用ai,生成单元测试用例

using System.Text.Json; using Moq; using TsRoslyn.Core.Api; using XieYun.Application.Services; namespace XieYun.Application.Test.Services; public class TestData { public required string Name { get; init; } public required int Value { get; init; } } [TestFixture] [TestOf(typeof(LocalStore<>))] public class LocalStoreTest { private Mock<IWxApi> _wxApiMock; private LocalStore<TestData> _localStore; [SetUp] public void Setup() { _wxApiMock = new Mock<IWxApi>(); _localStore = new LocalStore<TestData>(_wxApiMock.Object); } [Test] public async Task GetAsync_WhenNotInitializedAndNoStorageData_ReturnsNull() { // Arrange _wxApiMock.Setup(x => x.GetStorageAsync(typeof(TestData).ToString())) .ReturnsAsync((string?)null); // Act var result = await _localStore.GetAsync(); // Assert Assert.That(result, Is.Null); _wxApiMock.Verify(x => x.GetStorageAsync(typeof(TestData).ToString()), Times.Once); } [Test] public async Task GetAsync_WhenNotInitializedAndHasStorageData_ReturnsDeserializedData() { // Arrange var testData = new TestData { Name = "Test", Value = 123 }; var serializedData = JsonSerializer.Serialize(testData); _wxApiMock.Setup(x => x.GetStorageAsync(typeof(TestData).ToString())) .ReturnsAsync(serializedData); // Act var result = await _localStore.GetAsync(); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Name, Is.EqualTo(testData.Name)); Assert.That(result.Value, Is.EqualTo(testData.Value)); _wxApiMock.Verify(x => x.GetStorageAsync(typeof(TestData).ToString()), Times.Once); } [Test] public async Task GetAsync_WhenAlreadyInitialized_ReturnsCachedDataWithoutApiCall() { // Arrange var testData = new TestData { Name = "Cached", Value = 456 }; _localStore.SetAsync(testData).Wait(); // Initialize and cache data // Act var result = await _localStore.GetAsync(); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Name, Is.EqualTo(testData.Name)); Assert.That(result.Value, Is.EqualTo(testData.Value)); _wxApiMock.Verify(x => x.GetStorageAsync(It.IsAny<string>()), Times.Never); } [Test] public async Task SetAsync_SerializesDataAndStoresInApi() { // Arrange var testData = new TestData { Name = "New", Value = 789 }; string? storedValue = null; _wxApiMock.Setup(x => x.SetStorageAsync(typeof(TestData).ToString(), It.IsAny<string>())) .Callback<string, string>((_, value) => storedValue = value) .Returns(Task.CompletedTask); // Act await _localStore.SetAsync(testData); // Assert _wxApiMock.Verify(x => x.SetStorageAsync(typeof(TestData).ToString(), It.IsAny<string>()), Times.Once); var deserialized = JsonSerializer.Deserialize<TestData>(storedValue); Assert.That(deserialized, Is.Not.Null); Assert.That(deserialized.Name, Is.EqualTo(testData.Name)); Assert.That(deserialized.Value, Is.EqualTo(testData.Value)); } [Test] public async Task SetAsync_UpdatesCachedData() { // Arrange var initialData = new TestData { Name = "Initial", Value = 111 }; var newData = new TestData { Name = "Updated", Value = 222 }; await _localStore.SetAsync(initialData); // Act await _localStore.SetAsync(newData); var result = await _localStore.GetAsync(); // Assert Assert.That(result, Is.Not.Null); Assert.That(result.Name, Is.EqualTo(newData.Name)); Assert.That(result.Value, Is.EqualTo(newData.Value)); } [Test] public async Task GetAsync_AfterSet_ReturnsCachedDataWithoutApiCall() { // Arrange var testData = new TestData { Name = "Cached", Value = 333 }; await _localStore.SetAsync(testData); // Act var result = await _localStore.GetAsync(); // Assert Assert.That(result, Is.Not.Null); _wxApiMock.Verify(x => x.GetStorageAsync(It.IsAny<string>()), Times.Never); } [Test] public async Task MultipleGets_OnlyFetchesFromApiOnce() { // Arrange var testData = new TestData { Name = "Test", Value = 444 }; var serializedData = JsonSerializer.Serialize(testData); _wxApiMock.Setup(x => x.GetStorageAsync(typeof(TestData).ToString())) .ReturnsAsync(serializedData); // Act await _localStore.GetAsync(); await _localStore.GetAsync(); await _localStore.GetAsync(); // Assert _wxApiMock.Verify(x => x.GetStorageAsync(typeof(TestData).ToString()), Times.Once); } }

这样子就可以很轻松的使用C#的原生能力,进行测试。

应用项目里通过依赖注入,就能把js注入进来

serviceCollection.AddSingleton<IWxApi, WxApi>(); serviceCollection.AddSingleton<IStore<UserInfoStoreData>, LocalStore<UserInfoStoreData>>();
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/27 21:17:29

22、DB2 应用开发入门指南

DB2 应用开发入门指南 1. Python 操作 DB2 数据库练习 在这个练习中,我们将实践编写一个小型 Python 脚本来访问 SAMPLE 数据库中的数据。具体步骤如下: 1. 登录服务器 :以实例所有者的身份登录服务器。在 Linux 上通常是 db2inst1 ,在 Windows 上通常是 db2admin …

作者头像 李华
网站建设 2026/9/25 15:07:06

什么是负载均衡?不就是加台服务器嘛!

你是小阿巴&#xff0c;刚刚开发上线了自己的第一个网站。 前几天只有几个人访问&#xff0c;网站运行得稳稳当当。 你得意地想&#xff1a;做网站也太简单了吧&#xff01; 结果一周后&#xff0c;某知名博主 “鱼蛋” 不小心推广了 你的网站&#xff0c;突然来了 1 万个用户…

作者头像 李华
网站建设 2026/9/27 8:11:53

19、深入了解 DB2 应用程序开发:PHP 与 Perl 的实践指南

深入了解 DB2 应用程序开发:PHP 与 Perl 的实践指南 1. PHP 与 DB2 应用开发基础 在使用 PHP 进行 DB2 应用开发时,首先要掌握基本的数据库连接和资源管理。以下是一个使用 PDO_ODBC 连接到 DB2 数据库并释放连接资源的示例代码: // for PDO_ODBC $dbh = new PDO(odbc:s…

作者头像 李华
网站建设 2026/9/27 6:58:14

LC.1008 | 前序遍历构造二叉搜索树 | 树 | 递归遍历

输入&#xff1a; 一个整数数组 preorder&#xff0c;代表二叉搜索树的先序遍历结果。 要求&#xff1a; 根据给定的先序遍历还原出二叉搜索树&#xff08;BST&#xff09;。 BST 的性质是&#xff1a;对于任意节点&#xff0c;左子树所有节点值 < 当前节点值 < 右子树所…

作者头像 李华