none
TestScheduler, Concat and Do

    Pergunta

  • Hello,

    I have a ViewModel that subscribes to a client connection event.
    When the event is raised, I serialize the call to 5 client methods using Concat.
    When a method returns, I update some progress indicators.

    This works fine in production (with real objects). Notice that I do not use ObserveOnScheduler, but rather ObserveOn.
    In production, I inject the DispatcherScheduler, and in tests, a TestScheduler.

    _Client.Connected.Do(t =>
    {
    	SetProgress(0, "Starting");
            _Client.Method1()
    		.Do(v => SetProgress(20, "Text info"))
            	.Concat<object>(_Client.Method2()
    				       .Do(u => SetProgress(40, "Text info")))
    		.Concat<object>(_Client.Method3()
    				       .Do(u => SetProgress(60, "Text info")))
            	.Concat<object>(_Client.Method4()
    				       .Do(u => SetProgress(80, "Text info")))
    		.Concat<object>(_Client.Method5()
    				       .ObserveOn(dispatcherScheduler)
    				       .Do(u =>
    				       {
    				       		SetProgress(100, "Done!");
    				       		//...Update UI consequently
    				       })).Subscribe();
    }).Subscribe();

    Now, I created a Unit Test to verify that when the client connected event is raised, all 5 methods are called and at the
    end the progress indicators are set to 100 and Done!

    To do this, I used a TestScheduler to setup observables for a fake client. I used Moq to verify that the method were called,
    and some assertions at the end to verify the progress indicators.

    The code looks like this:

    [Test]
    public void GetStuffFromClientWhenConnected()
    {
    	
    	_ClientMock.SetupGet(t => t.Connected)
            	   .Returns(_DispatcherScheduler.CreateHotObservable(ReactiveTest.OnNext(1, new EventPattern<EventArgs>(null, null))));
    
    	_ClientMock.Setup(t => t.Method1())
            	   .Returns(_DispatcherScheduler.CreateHotObservable(ReactiveTest.OnNext(3, new FakeData())));
    
    	_ClientMock.Setup(t => t.Method2())
    		   .Returns(_DispatcherScheduler.CreateHotObservable(ReactiveTest.OnNext(4, new FakeData())));
    
    	_ClientMock.Setup(t => t.Method3())
            	   .Returns(_DispatcherScheduler.CreateHotObservable(ReactiveTest.OnNext(5, new FakeData())));
    
    	_ClientMock.Setup(t => t.Method4())
            	   .Returns(_DispatcherScheduler.CreateHotObservable(ReactiveTest.OnNext(6, new FakeData())));
    
    	_ClientMock.Setup(t => t.Method5())
    		   .Returns(_DispatcherScheduler.CreateHotObservable(ReactiveTest.OnNext(7, new FakeData())));
    
    	var vm = CreateViewModel();
    
    	_DispatcherScheduler.AdvanceTo(8);
    
    	_ClientMock.Verify(t => t.Method1());
    	_ClientMock.Verify(t => t.Method2());
    	_ClientMock.Verify(t => t.Method3());
    	_ClientMock.Verify(t => t.Method4());
    	_ClientMock.Verify(t => t.Method5());
    
    	Assert.That(vm.Progress, Is.EqualTo(100));
    	Assert.That(vm.ProgressText, Is.EqualTo("Done"));
    }

    The connected event is raised, the 5 methods are called, but the progress indicators stay at 20, "Text Info".
    I wonder why. I registered and raised these events using the TestScheduler.AdvanceTo(8).
    It looks like only Method1 completed event was raised.

    Any advice?

    Regards
    Louis-Pierre Beaumont


    quarta-feira, 28 de março de 2012 16:48

Respostas