当前位置: 首页 > news >正文

使用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>>();
http://www.cnnetsun.cn/news/65006.html

相关文章:

  • 基于28DR+VU13P的宽带高速信号处理板
  • AutoGPT镜像上线促销:限时赠送免费Token额度
  • 达人内容乱+不合规?KOL/KOS/KOC/KOC/KOX内容协同+合规管控,品牌调性不跑偏
  • 解锁优质创意素材:这四个专业平台值得收藏
  • 毕设分享 深度学习遮挡下的人脸识别(源码+论文)
  • Python UV搭配Miniconda:下一代包管理体验
  • 实验室装修,怎样做更省心?
  • Redis多数据源配置指南
  • AutoGPT支持ONNX Runtime部署了吗?跨框架兼容测试
  • 零基础小白网络安全入行清单:学技术前,先搞定这6件“小事”
  • 计算机毕业设计springboot小区送货系统 基于SpringBoot的社区末端智能配送平台 面向住宅区的 轻量级电商物流管理系统
  • GitHub组织账号管理Qwen3-32B项目协作开发流程
  • 毕设项目分享 基于大数据的招聘职业爬取与分析可视化
  • vLLM镜像实测:连续批处理让Qwen推理效率翻倍
  • LabVIEW 携手 YOLOv8:全方位视觉处理的奇妙之旅
  • 某雷赛86闭环步进驱动方案-HBS86H整体方案及原理图、PCB、无错无警告代码打包
  • 【从0到1学RabbitMQ】十分钟上手 RabbitMQ:Docker 部署 + Spring Boot 自动化配置全攻略
  • 【论文笔记•(多智能体)】A Knowledge-driven Adaptive Collaboration of LLMs for Enhancing Medical Decision-making
  • 通过SEO推广LobeChat博客内容,带动大模型Token购买转化
  • 【Svelte】重定向页面
  • 基于SpringBoot的日用品仓储管理系统的设计与实现
  • 基于SpringBoot的校园论坛交流系统
  • AutoGPT如何处理模糊目标?自然语言理解边界探讨
  • 清华镜像站推荐:Miniconda下载提速80%的秘密武器
  • update.py update脚本 git一键上传push脚本 - Git自动化推送代码的几种方式及实用脚本
  • 从GitHub获取Qwen3-8B最新镜像并完成本地化部署
  • Ubuntu安装完成后配置PyTorch-GPU的完整流程
  • 购买GPU算力租用Qwen3-14B实例的性价比分析
  • LobeChat前端性能优化建议:减少加载时间提升访问量
  • 学术研究新利器:Qwen3-8B开箱即用镜像发布