【问题标题】:Unit testing ReactiveUI view models and commands单元测试 ReactiveUI 视图模型和命令
【发布时间】:2018-11-30 22:41:39
【问题描述】:

我有一个使用 ReactiveUI 实现的工作视图,现在我正在尝试为我的视图模型编写一些单元测试,但是从测试中使用时我的视图模型似乎不起作用。

具体来说,执行命令似乎不会触发订阅者。在下面的这个测试中,我正在调用 AddPlayer 命令,但订阅的处理程序没有运行:

public class NewGameViewModelTests
{
    private NewGameViewModel viewmodel;

    public NewGameViewModelTests()
    {
        viewmodel = new NewGameViewModel();            
    }

    [Fact]
    public void CanAddUpToSevenPlayers()
    {
        foreach(var i in Enumerable.Range(1, 7))
        {
            viewmodel.NewPlayerName = "Player" + i;
            viewmodel.AddPlayer.Execute(null);
            Assert.Equal(i, viewmodel.Players.Count);
        }
    }
}

这是我正在测试的视图模型:

public class NewGameViewModel : ReactiveObject
{
    public ReactiveList<string> Players { get; private set; }
    public ReactiveCommand<Object> AddPlayer { get; private set; }
    public ReactiveCommand<Object> RemovePlayer { get; private set; }
    public ReactiveCommand<Object> StartGame { get; private set; }
    public ReactiveCommand<Object> RandomizeOrder { get; private set; }


    string newPlayerName;
    public string NewPlayerName {
        get { return newPlayerName; }
        set { this.RaiseAndSetIfChanged(ref newPlayerName, value); }
    }

    public NewGameViewModel()
    {
        Players = new ReactiveList<string> ();

        var canStart = this.Players.CountChanged.Select(count => count >= 3);
        StartGame = canStart.ToCommand();
        RandomizeOrder = canStart.ToCommand();

        RemovePlayer = ReactiveCommand.Create();
        AddPlayer = this.WhenAnyValue(x => x.Players.Count, x => x.NewPlayerName,
            (count, newPlayerName) => count < 7 && !string.IsNullOrWhiteSpace(newPlayerName) && !this.Players.Contains(newPlayerName))
            .ToCommand();

        RandomizeOrder.Subscribe(_ =>
        {
            using (Players.SuppressChangeNotifications())
            {
                var r = new Random();
                var newOrder = Players.OrderBy(x => r.NextDouble()).ToList();
                Players.Clear();
                Players.AddRange(newOrder);
            }
        });

        RemovePlayer.Subscribe(player =>
        {
            this.Players.Remove((string)player);
        });

        AddPlayer.Subscribe(_ =>
        {
            Players.Add(NewPlayerName.Trim());
            NewPlayerName = string.Empty;
        });
    }
}

【问题讨论】:

  • 您的代码看起来正确,我使用 RxUI 6.0.1 将其复制并粘贴到我的机器上,测试通过了。我所做的唯一更改是将测试转换为 NUnit,它只需要重命名属性并更改断言语法。你这里一定有其他事情吗?

标签: c# reactiveui


【解决方案1】:

使用 ReactiveUI master 在我的机器上似乎没有失败。也许还有其他事情发生?

编辑:这是带有 Xamarin.Forms 的 ReactiveUI 中的一个错误,要解决它,请将其添加到在测试运行开始时运行的某个位置:

RxApp.MainThreadScheduler = Scheduler.CurrentThread;

【讨论】:

  • 好的,所以问题似乎出在 reactiveui-xamforms 6.0.3。当我删除测试项目中的引用时,测试开始通过。这是一个错误吗?
  • 这是 ReactiveUI 中的一个错误,感谢跟踪
  • 这已在 ReactiveUI 6.0.4 中修复,更新它应该会消失 :)
  • 这修复了我的测试(ReactiveUI 9.19.5)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-12
  • 2020-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-16
相关资源
最近更新 更多