【问题标题】:Testing with bUnit and Moq a razor component that uses Fluxor使用 bUnit 和 Moq 测试使用 Fluxor 的剃须刀组件
【发布时间】:2021-08-11 05:45:27
【问题描述】:

我在我的 Blazor 应用程序的一个 razor 组件中使用 Fluxor 进行状态管理,但我不确定如何设置它以使用 Moq 进行测试。我不能仅仅为学生分配一个价值,因为它是一个仅限于初始化的属性。是否有设置 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 = )

【问题讨论】:

  • 这是一个最小起订量问题,而不是真正的 bUnit 问题。无论如何,看看github.com/Moq/moq4/wiki/Quickstart#properties。它解释了如何定义属性的返回值,例如mock.Setup(foo =&gt; foo.Name).Returns("bar");

标签: blazor moq xunit state-management fluxor


【解决方案1】:

我被困在这个问题上很长一段时间,但浏览了 Fluxor 的 glitter community 并发现了一些可能有帮助的东西!我知道您想使用 Moq 进行测试,但也许我发现的可能更容易/适合您测试 Fluxor 组件的目的!

我没有使用最小起订量,而是遵循this 格式并设法使某些东西正常工作:

Test.cs

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。请参考我的目录结构here(您会了解我是如何决定要包含哪些内容的)。

Actions.cs

public class SetInhousePetOwnerListAction
{
    public List<InhousePetOwner> InhousePetOwners { get; }
    public SetInhousePetOwnerListAction(List<InhousePetOwner> inhousePetOwners)
    {
        InhousePetOwners = inhousePetOwners;
    }
}

Reducers.cs(在构造函数中扫描)

public static class Reducers
{
    [ReducerMethod]
    public static InhousePetOwnerListState ReduceSetInhousePetOwnerListAction(InhousePetOwnerListState state, SetInhousePetOwnerListAction action)
    {
        return new InhousePetOwnerListState(inhousePetOwners: action.InhousePetOwners);
    }
}

InhousePetOwnerState.cs(在构造函数中扫描)

public class InhousePetOwnerListState
{
    public List<InhousePetOwner> InhousePetOwners { get; }

    private InhousePetOwnerListState() { }

    public InhousePetOwnerListState(List<InhousePetOwner> inhousePetOwners)
    {
        InhousePetOwners = inhousePetOwners;
    }
}

此解决方案的作用是允许您注入所有 Fluxor 状态、动作和减速器,使您能够像往常一样调用它们 - 我发现这种方式很容易测试!

【讨论】:

  • 从您的 Reducers.cs cs 文件中,我看不到您在 InhousePetOwnerStateTests 的构造函数中用来扫描的 Reducers 类型的定义。我说的是这条线.ScanTypes(typeof(InhousePetOwnerListState), **typeof(Reducers)**));
  • @RobertMrobo 感谢您的评论!我已经更新了上面的文件以反映 Reducers.cs 的定义;希望现在更清楚了!
  • 对于使用 Effects 且依赖于您自己编写的服务的任何人,请注意:您需要在测试上下文中注册模拟服务,以便 IoC 可以创建它们。如果不这样做,IoC 将尝试初始化 Fluxor 并失败,因为它找不到自定义服务。
【解决方案2】:

我这样做的方式是使用设置返回完整的状态记录,按照我想要的方式进行配置。

如果你有一个 StudentState 是只读的 IState

你可以这样做:

       var studentState = new Mock<IState<StudentsState>>();
            studentState.Setup(s => s.Value)
             .Returns(
                new StudentsState 
                  { 
                      Students = new List<StudentRecord> 
                         { ... }
                   });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-20
    • 2020-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-15
    相关资源
    最近更新 更多