我在 Blazor 应用程序的一个剃刀组件中使用 Fluxor 进行状态管理,但我不太确定如何设置它以使用 Moq 进行测试。我不能只为学生赋值,因为它只是一个 init 属性。有没有具体的方法来设置 Fluxor 进行测试?
代码
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>>();
// Help here
StudentsState.Setup(t => t.Value.Students = )
我在这个问题上停留了很长一段时间,但浏览了 Fluxor 的 glitter 社区,发现了一些可能有帮助的东西!我知道您想使用 Moq 进行测试,但也许我发现的可能更容易/适合您测试 Fluxor 组件的目的!
我没有使用起订量,而是遵循 this 格式并设法让一些东西起作用:
public class InhousePetOwnerStateTests
{
private readonly IServiceProvider ServiceProvider;
private readonly IStore Store;
private readonly IState<InhousePetOwnerListState> State;
public InhousePetOwnerStateTests()
{
var services = new ServiceCollection();
services.AddFluxor(x =>
x
.ScanAssemblies(GetType().Assembly)
.ScanTypes(typeof(InhousePetOwnerListState), typeof(Reducers)));
ServiceProvider = services.BuildServiceProvider();
Store = ServiceProvider.GetRequiredService<IStore>();
State = ServiceProvider.GetRequiredService<IState<InhousePetOwnerListState>>();
Store.InitializeAsync().Wait();
}
[Fact]
public void SetInhousePetOwnerList_Empty_StateUpdated()
{
Store.Dispatch(new SetInhousePetOwnerListAction(new()));
Assert.Empty(State.Value.InhousePetOwners);
}
[Fact]
public void SetInhousePetOwnerList_MultipleInhouseOwners_StateUpdated()
{
List<InhousePetOwner> inhousePetOwners = new List<InhousePetOwner>
{
new InhousePetOwner()
{
InhousePetOwnerId = 1,
PetOwnerId = 1,
TimeIn = System.DateTime.Now
},
new InhousePetOwner()
{
InhousePetOwnerId = 2,
PetOwnerId = 2,
TimeIn = System.DateTime.Now
},
};
Store.Dispatch(new SetInhousePetOwnerListAction(inhousePetOwners));
Assert.Equal(2, State.Value.InhousePetOwners.Count);
}
}
在构造函数中,我们创建一个服务集合并添加 Fluxor(就像添加到 Startup.cs 中一样),然后扫描程序集。
在上面的代码中,我扫描了Reducers 和State。请参阅我的目录结构(您将了解我如何决定包含哪些内容)。
public class SetInhousePetOwnerListAction
{
public List<InhousePetOwner> InhousePetOwners { get; }
public SetInhousePetOwnerListAction(List<InhousePetOwner> inhousePetOwners)
{
InhousePetOwners = inhousePetOwners;
}
}
public static class Reducers
{
[ReducerMethod]
public static InhousePetOwnerListState ReduceSetInhousePetOwnerListAction(InhousePetOwnerListState state, SetInhousePetOwnerListAction action)
{
return new InhousePetOwnerListState(inhousePetOwners: action.InhousePetOwners);
}
}
public class InhousePetOwnerListState
{
public List<InhousePetOwner> InhousePetOwners { get; }
private InhousePetOwnerListState() { }
public InhousePetOwnerListState(List<InhousePetOwner> inhousePetOwners)
{
InhousePetOwners = inhousePetOwners;
}
}
这个解决方案的作用是允许您注入所有 Fluxor 状态、操作和减速器,使您能够像平常一样调用它们 - 我发现通过这种方式进行测试非常容易!
我这样做的方法是使用设置返回整个状态记录,按照我想要的方式配置。
因此,如果您有一个 IState,其中 StudentsState 是只读的
你可以这样做:
var studentState = new Mock<IState<StudentsState>>();
studentState.Setup(s => s.Value)
.Returns(
new StudentsState
{
Students = new List<StudentRecord>
{
new StudentRecord(),
new StudentRecord(),
}
});
TestContext = new Bunit.TestContext();
TestContext.Services.AddScoped(_ => studentState.Object);
var cut = TestContext.RenderComponent<StudentListComponent>();
var studentRows = cut.FindAll(".student-row");
Assert.AreEqual(2, studentRows.Count, "Should have one row for each student in the state");