2013-11-03 107 views
4

我正在使用Xamarin Studio使用MvvmCross开始TDD。我试图首先测试发布到视图模型的消息的效果,以便只有在收到适当的消息时才执行逻辑。如何使用IMvxMessenger对MvvmCross进行单元测试

我将Stuart的一些优秀教程一起入侵,导致位置数据成功传播以查看模型,然后更新iOS视图中的一些文本控件,地图标记等。

但是在我进一步深入之前,我想使用TDD进行编码。我如何人工设置视图模型并在我的测试工具中人为地发布消息给它? :

public class MyViewModel : MvxViewModel 
{ 
    private readonly MvxSubscriptionToken _token; 

    public MyViewModel(ILocationService service, IMvxMessenger messenger) 
    { 
     //weak reference 
     _token = messenger.Subscribe<LocationMessage>(OnLocationMessage); 
    } 

    private void OnLocationMessage(LocationMessage locationMessage) 
    { 
     Lat = locationMessage.Lat; 
     Lng = locationMessage.Lng; 
     // Console.WriteLine("on loc msg {0:0.0000}, {1:0.0000}", Lat, Lng); 
    } 

    private double _lng; 
    public double Lng 
    { 
     get { return _lng; } 
     set 
     { 
      _lng = value; 
      RaisePropertyChanged(() => Lng); 
     } 
    } 

    private double _lat; 
    public double Lat 
    { 
     get { return _lat; } 
     set 
     { 
      _lat = value; 
      RaisePropertyChanged(() => Lat); 
     } 
    } 
} 


[TestFixture()] 
public class LocTest 
{ 
    [Test()] 
    public void LocationMessageIsRecieved() 
    { 
     // im using nsubstitute to mock with 
     var locService = Substitute.For<ILocationService>(); 
     var msgr = Substitute.For<IMvxMessenger>(); 
     var vm = new Map2ViewModel(locService, msgr); 

     var locMsg = new LocationMessage(this, 1F, 2F); 
     msgr.Publish(locMsg); 

     var lat = vm.Lat; 
     Assert.AreEqual(2F, lat); // says lat is 0.0 and nunit doesnt let me debug the tests :(
    } 
} 

与MvvmCross TDD任何伟大的教程将是非常美妙

+0

您基本上可以创建MvxMessengerHub,如Greg Shackles github回购所示(请参阅下面的Stuart答案中的链接) –

回答

8

在TDD任何伟大的教程与MvvmCross将是非常美妙

格雷格镣铐的在演变的谈话是一个很好的起点为此的位置 - http://xamarin.com/evolve/2013#session-7wb0etd3r8

他的CodeCamp示例包含一组极好的单元测试示例 - http://www.gregshackles.com/2013/09/nyc-code-camp-8-mobile-apps/导致https://github.com/gshackles/NycCodeCamp8/tree/master/CodeCamp.Core/tests/CodeCamp.Core.Tests/ViewModelTests

上MvvmCross单元测试教程 - 包括嘲讽 - 是http://mvvmcross.wordpress.com/

在N = 29获得博客中,也可在http://blog.fire-development.com/2013/06/29/mvvmcross-enable-unit-testing/

2

我如何人为地设置了viewmodel并在我的测试工具中人为地发布消息给它? :

在上link斯图尔特张贴描述设置后,将图案我已经用于测试MvxMessenger是使用Moq(连同AutoFixture),以创建一个模拟IMvxMessenger并注入它:

_mockMvxMessenger = Fixture.Freeze<Mock<IMvxMessenger>>(); 
_myViewModel = _fixture.Build<MyViewModel().OmitAutoProperties().Create(); 

以上假设您将IMvxMessenger注入ViewModel。

如果您需要检查的消息已经公布,您可以断言(验证)在模拟

_myViewModel.MyCommand.Execute (null); 
_mockMvxMessenger.Verify (m => m.Publish (It.IsAny<MyMvxMessage>()), Times.Once); 

如果您需要触发的消息,然后抓住订阅行动和你的时候火了像

冻结素后视图模型,但建设之前:

private Action<MyMvxMessage> _callbackAction; // class scope var 
_mockMvxMessenger.Setup (n => n.Subscribe<MyMvxMessage> (It.IsAny<Action<MyMvxMessage>>(), It.IsAny<MvxReference>(), It.IsAny<string>())).Callback<Action<MyMvxMessage>, MvxReference, string> ((action,mvxref,tag) => _callbackAction = action); 
在测试

然后你可以“火消息”通过只调用

_callbackAction(new MyMvxMessage(this)); 
相关问题