news 2026/4/23 13:29:04

使用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/4/23 12:29:42

直流耦合1G采集卡

1GS/s采样率 14bit分辨率 1/2/4通道同步采集&#xff0c;高采样率&#xff08;1GS/s&#xff09;与高分辨率&#xff08;14bit&#xff09;的高速数字化仪/高速数据采集卡。集成直流耦合程控放大器&#xff0c;支持双极性宽带信号输入&#xff0c;具备高动态范围采集能力。该…

作者头像 李华
网站建设 2026/4/23 11:25:37

大模型压缩技术全解析:从剪枝到量化,程序员必学收藏指南

本文详细介绍了大模型压缩技术&#xff0c;包括剪枝(移除冗余连接)、量化(降低数值精度)和知识蒸馏(教师-学生模式)三大核心方法&#xff0c;并推荐了"知识蒸馏→剪枝→量化"的组合优化流程。通过系统压缩技术&#xff0c;可将庞大模型转化为轻量化模型&#xff0c;实…

作者头像 李华
网站建设 2026/4/15 16:26:25

LC.701 | 二叉搜索树中的插入操作 | 树 | 迭代模拟

输入&#xff1a; 二叉搜索树的根节点 root 和一个待插入的整数 val。 要求&#xff1a; 将 val 插入到二叉搜索树中&#xff0c;并保证插入后整棵树仍然满足 BST 的性质&#xff08;左 < 根 < 右&#xff09;。 题目保证新值和原始树中任意节点值都不同。 输出&#xff…

作者头像 李华
网站建设 2026/4/21 20:50:03

多元异构数据库管理:从“人肉运维”到统一平台的省心之路

在当前企业数字化转型的浪潮下&#xff0c;一个普遍的技术现实是&#xff1a;几乎不存在完全单一的数据技术栈。从传统的Oracle、MySQL到新兴的Redis、MongoDB、ClickHouse&#xff0c;再到各类国产数据库&#xff0c;多元异构的数据库环境已成为企业数据架构的常态。面对这种复…

作者头像 李华
网站建设 2026/4/20 20:04:02

LobeChat能否接入微信机器人?实现路径技术推演

LobeChat 能否接入微信机器人&#xff1f;技术实现路径深度解析 在智能对话系统加速落地的今天&#xff0c;越来越多开发者开始思考&#xff1a;如何让私有化部署的大模型助手走出浏览器&#xff0c;真正融入用户的日常沟通场景&#xff1f;一个高频需求浮出水面——能否将像 L…

作者头像 李华
网站建设 2026/4/22 14:29:43

毕设开源 大数据B站数据分析与可视化

文章目录0 前言1 课题背景2 实现效果3 数据获取4 数据可视化0 前言 &#x1f525;这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff0c;这两年不断有学弟学妹告诉学长自己做的项目系统…

作者头像 李华