使用SelectMany在ReactiveUI中调用异步方法的单元测试视图模型

时间:2018-10-23 13:36:49

标签: unit-testing tdd system.reactive reactiveui

我是ReactiveUI的新手,正在尝试测试如下所示的视图模型:

public interface IService
{
    Task<SessionModel> GetData(string id);
}

/// Provides a group of schedulers available to be used
public interface ISchedulers
{
    IScheduler Default { get; }
    IScheduler Dispatcher { get; }
}

public class MyVm : ReactiveObject
{
    IService service;

    public MyVm(ISchedulers schedulers, IService service)
    {
        this.service = service;
        this.session = this.WhenAnyValue(x => x.SessionId)
                           .SelectMany(SearchSession)
                           .ObserveOn(schedulers.Default)
                           .ToProperty(this, x => x.Session);
    }

    private async Task<SessionModel> SearchSession(string id)
    {
        return await this.service.GetData(id);
    }

    private string sessionId;
    public string SessionId
    {
        get => sessionId;
        set => this.RaiseAndSetIfChanged(ref sessionId, value);
    }


    readonly ObservableAsPropertyHelper<SessionModel> session;
    public SessionModel Session
    {
        get { return session.Value; }
    }

}

public class SessionModel { }

我正在模拟服务调用以返回虚拟数据,但不确定如何使用TestScheduler才能使SelectMany正常工作。

这是一个测试类,显示了我将如何为视图模型创建测试。目标是最终能够检查是否已设置模型:

[TestClass]
public class MyVmTests
{
    [TestMethod]
    public void CreateClass
    {
       var subject = new MyVm(/*pass in mocks*/);

       subject.SessionId="test";

       Assert.IsNotNull(subject.Session);
     }
}

1 个答案:

答案 0 :(得分:0)

我认为没有必要使用TestScheduler。以下对我来说有用(使用Moq):

var mockSchedulers = new Mock<ISchedulers>();
mockSchedulers.Setup(s => s.Default).Returns(Scheduler.Immediate);
var id = "123";
var mockService = new Mock<IService>();
var returnSession = new SessionModel();
mockService.Setup(s => s.GetData(It.Is<string>(i => i == id)))
    .ReturnsAsync(returnSession);
var target = new MyVm(mockSchedulers.Object, mockService.Object);

target.SessionId = id;

Assert.IsNotNull(target.Session);
Assert.AreEqual(returnSession, target.Session);

TestScheduler是最好的选择,当您尝试随时间测试某些东西(例如Delay,证明Delay实际上发生了)时。您不是真的在这里这样做。