2015-06-08 3 views
0

Как написать тест NUnit для MvvmCross MvxCommand, когда моей команде требуется CommandParameter типа integer.Как проверить MvvmCross MvxCommand <int> с NUnit

testListViewModel.EditCommand.Execute(null); 

Этот вариант не является вариантом, так как у меня есть этот ViewModel. CanExecute продолжается, если параметр передан.

public class TestListViewModel : MvxViewModel 
{ 
    private readonly ITestService _testService; 
    private readonly IDialogService _dialogService; 
    public TestListViewModel(ITestService testService, IDialogService dialogService) 
    { 
     _testService = testService; 
     _dialogService = dialogService; 
    } 

    public MvxCommand<int> EditCommand { get { return new MvxCommand<int>(Edit, id => id > 0); } }  

    private void Edit(int asTestID) { ShowViewModel<TestViewModel>(new { asTestID }); } 
} 

Я использую ссылки NUnit + Moq + Cirrious.MvvmCross.Test.Core в моем тестовом проекте и имеют такую ​​структуру.

public class MockDispatcher : MvxMainThreadDispatcher, IMvxViewDispatcher 
{ 
    public readonly List<MvxViewModelRequest> Requests = new List<MvxViewModelRequest>(); 
    public readonly List<MvxPresentationHint> Hints = new List<MvxPresentationHint>(); 
    public bool RequestMainThreadAction(Action action) 
    { 
     action(); 
     return true; 
    } 

    public bool ShowViewModel(MvxViewModelRequest request) 
    { 
     Requests.Add(request); 
     return true; 
    } 

    public bool ChangePresentation(MvxPresentationHint hint) 
    { 
     Hints.Add(hint); 
     return true; 
    } 
} 

[TestFixture] 
class TestListViewModelTest : MvxIoCSupportingTest 
{ 
    [Test] 
    public void TestListViewModel_OnEdit_ShowTestViewModel() 
    { 
     //Arrange 
     base.ClearAll(); 

     var mockDispatcher = new MockDispatcher(); 
     Ioc.RegisterSingleton<IMvxViewDispatcher>(mockDispatcher); 
     Ioc.RegisterSingleton<IMvxMainThreadDispatcher>(mockDispatcher); 

     var mockDialogService = new Mock<IDialogService>(); 
     var mockTestService = new Mock<ITestService>(); 

     var testListViewModel = new TestListViewModel(mockTestService.Object, mockDialogService.Object); 

     //Act 
     testListViewModel.EditCommand.Execute(2); //this line is failing 

     //Assert 
     Assert.AreEqual(1, mockDispatcher.Requests.Count); 
     var request = mockDispatcher.Requests[0]; 
     Assert.AreEqual(typeof(TestViewModel), request.ViewModelType); 
     Assert.AreEqual((2).ToString(), request.ParameterValues["asTestID"]); 
    } 
} 

Когда я запустить тест он бросает MvxIoCResolveException с этим стеком вызовов. Я попытался отлаживать его, и мой код буквально терпит неудачу в MvxNavigatingObject.ShowViewModel(), где параметр является объектом и пытается вызвать параметрValuesObject.ToSimplePropertyDictionary().
В статической функции ToSimplePropertyDictionary (этот объект вход)propertyInfos перечислитель имеет нулевое значение, так что не могу назвать Еогеасп (VAR PropertyInfo в propertyInfos).

Стек вызовов, которые я получаю от выполнения теста является:

Cirrious.CrossCore.Exceptions.MvxIoCResolveException : Failed to resolve type Cirrious.MvvmCross.Platform.IMvxStringToTypeParser 
    at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.Resolve(Type t) 
    at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.Resolve() 
    at Cirrious.MvvmCross.MvxSingletonCache.get_Parser() 
    at Cirrious.MvvmCross.Platform.MvxSimplePropertyDictionaryExtensionMethods.<ToSimplePropertyDictionary>b__7(PropertyInfo property) 
    at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext() 
    at Cirrious.MvvmCross.Platform.MvxSimplePropertyDictionaryExtensionMethods.ToSimplePropertyDictionary(Object input) 
    at Cirrious.MvvmCross.ViewModels.MvxNavigatingObject.ShowViewModel(Object parameterValuesObject, IMvxBundle presentationBundle, MvxRequestedBy requestedBy) 
    at App.Core.ViewModels.TestListViewModel.Edit(Int32 asTestID) in TestListViewModel.cs: line 37 
    at App.Tests.Test.TestListViewModelTest.TestListViewModel_OnEdit_ShowTestViewModel() in TestListViewModelTest.cs: line 97 

Любая помощь будет оценен по достоинству!

ответ

0

Когда вы вызываете ShowViewModel с параметром, есть несколько способов сделать это. Это определяет, как MvvmCross называет ваш метод Init.

  • отдельных просто-типизированных параметры
  • один параметр типизированного объект с просто-типизированными свойствами
  • , как InitFromBundle() с параметром IMvxBundle - этот последний аромат всегда поддерживали через интерфейс IMvxViewModel.

Вы звоните ShowViewModel с анонимным типом, но без имен свойств. Эти имена свойств должны соответствовать именам параметров в вашем методе Init.

Таким образом, вместо этого:

private void Edit(int asTestID) { ShowViewModel<TestViewModel>(new { asTestID }); } 

ли это:

// simply-Typed parameters 
private void Edit(int asTestID) { ShowViewModel<TestViewModel>(asTestID); } 

Или это:

// a single Typed parameter object with simply-Typed properties 
private void Edit(int asTestID) { ShowViewModel<TestViewModel>(new { ID = asTestID }); } 

См https://github.com/MvvmCross/MvvmCross/wiki/View-Model-Lifecycle#2-init

+0

Извините, но я не знаю, как обрабатывать ваш первый фрагмент кода в Init(). Второй фрагмент кода похож на мой. Это то же самое, что: 'private void Edit (int asTestID) {ShowViewModel (новый {asTestID = asTestID}); } ' –

+0

Он должен работать, если вы включаете имя свойства в свой анонимный тип. Вы все еще получаете ошибки? – Kiliman

+0

Да, я все еще не могу выполнить тест. –