如何使用bUnit与Moq测试依赖Fluxor的Blazor Razor组件
Fluxor + Moq 测试环境搭建及init属性赋值解决方案
核心问题解决
你遇到的init only属性无法直接赋值的问题不需要特殊的Fluxor配置,调整Mock的写法即可:
不要尝试直接对IState<T>.Value的内部属性做Setup,而是先构造完整的StudentsState实例(init only属性可在对象初始化器中合法赋值),再将该实例设置为IState<StudentsState>.Value的返回值。
完整的代码示例如下:
var teacherService = new Mock<ITeacherService>(); var localStorage = new Mock<ILocalStorageService>(); var studentService = new Mock<IStudentService>(); var toastService = new Mock<IToastService>(); var NavigationManager = new Mock<NavigationManager>(); var Dispatcher = new Mock<IDispatcher>(); var actionSubscriber = new Mock<IActionSubscriber>(); var StudentsState = new Mock<IState<StudentsState>>(); var TeacherState = new Mock<IState<TeacherState>>(); // 1. 先构造测试用的StudentsState实例,init属性在初始化器直接赋值 var testStudents = new List<Student> { new Student { Id = 1, Name = "张三" }, new Student { Id = 2, Name = "李四" } }; var mockStudentStateValue = new StudentsState { Students = testStudents, // 其他需要模拟的状态字段统一在这里赋值 }; // 2. 配置IState的Value属性返回上面构造的实例即可 StudentsState.Setup(s => s.Value).Returns(mockStudentStateValue);
进阶测试方案
如果需要模拟状态变化的场景,可以用SetupSequence返回多轮状态值:
var emptyState = new StudentsState { Students = Enumerable.Empty<Student>() }; var loadedState = new StudentsState { Students = testStudents }; StudentsState.SetupSequence(s => s.Value) .Returns(emptyState) // 首次访问返回初始状态 .Returns(loadedState); // 第二次访问返回加载完成后的状态
如果你是测试Razor组件,更推荐用bUnit搭配Fluxor原生的服务注入方案,不需要手动Mock大量依赖,更贴近真实运行场景:
using Bunit; using Fluxor; // 初始化bUnit测试上下文 using var testContext = new TestContext(); // 注入Fluxor相关服务,直接扫描业务程序集注册状态、Reducer、Effect等 testContext.Services.AddFluxor(opt => { opt.ScanAssemblies(typeof(StudentsState).Assembly); opt.UseRouting(); }); // 直接从上下文容器获取所需服务即可 var dispatcher = testContext.Services.GetRequiredService<IDispatcher>(); var studentState = testContext.Services.GetRequiredService<IState<StudentsState>>();
内容的提问来源于stack exchange,提问作者dtcdtcdtcdt
相关产品推荐
相关产品推荐

