2011-06-08 7 views
9

Mam następujący kod testowy:Błąd makrofotografii: poprzednia metoda "IEnumerator.MoveNext();" wymaga wartości zwracanej lub wyjątek rzucać

parentViewModel = MockRepository.GenerateMock<IParentViewModel>(); 
parentViewModel.Expect(x => x.GetPropertyValue<IEnumerable<Milestone>>("JobMilestones")).Return(new Milestone[0]); 

viewModel = new JobPenaltiesViewModel(j, new Penalty[0], _opContext, parentViewModel); 

Assert.That(viewModel.Milestones.Count(), Is.EqualTo(0)); 
parentViewModel.VerifyAllExpectations(); 

List<string> propsChanged = new List<string>(); 
viewModel.PropertyChanged += (s, e) => propsChanged.Add(e.PropertyName); 

parentViewModel.Raise(x => x.PropertyChanged += null, parentViewModel, new PropertyChangedEventArgs("JobMilestones")); 

AssertPropertiesChangedAsExepected(propsChanged, 1, "Milestones"); 

Milestone m1 = GenerateMilestone(j); 
List<Milestone> milestones1 = new List<Milestone> { m1 }; 
parentViewModel.Expect(x => x.GetPropertyValue<IEnumerable<Milestone>>("JobMilestones")).Return(milestones1).Repeat.Any(); 

IEnumerable<Milestone> milestones = viewModel.Milestones; 
Assert.That(milestones.Count(), Is.EqualTo(1)); 
parentViewModel.VerifyAllExpectations(); 

Wszystkie badania i twierdzenia uda się do:

Assert.That(milestones.Count(), Is.EqualTo(1)); 

To miejsce, gdzie pojawia się wyjątek:

Previous method 'IEnumerator.MoveNext();' requires a return value or an exception to throw. 

Próbowałem wszystkiego, co mogę wymyślić, a moje testy wydają się wskazywać, że parentViewModel Mock zwraca null lub em wyliczanie pty (np. kiedy używam debuggera do sprawdzenia zwróconej wartości, "Widok wyników" mówi, że wyliczenie nie zwróciło żadnych wyników).

Czego mi tu brakuje?

+1

Czy otrzymasz poprawny wynik, jeśli spróbujesz: 'IEnumerable kamieni milowych = parentViewModel.Milestones;' and 'Assert.That (kamienie milowe.Count(), Is.EqualTo (1))'? (Po prostu sprawdź gdzie straciłeś m1) – steenhulthin

+1

Nie, '' Assert.That (kamienie milowe.Count(), Is.EqualTo (1)) 'jest źródłem wyjątku. Nigdy nie dostaję się do 'parentViewModel.VerifyAllExpectations()' – CodingGorilla

+1

Ok, nie było jasne, co miałem na myśli. Miałem na myśli dodanie linii tuż po 'parentViewModel.Expect (x => x.GetPropertyValue > (" JobMilestones ")). Return (milestones1) .Repeat.Dowolne(); ', więc możesz wystąpić na' parentViewModel' przed potwierdzeniem na 'viewModel'. Aby sprawdzić, czy 'm1' jest w' parentViewModel.JobMileStones' (napisałem parentViewModel.MileStones w pierwszym komentarzu - moje złe.). – steenhulthin

Odpowiedz

0

Mam ponieważ usunięto kod przestępstwa; jednak nigdy nie zrozumiałem, dlaczego zachowywało się tak, jak było.

2

milestones.Count() jest wykonywany tak (jak to jest IEnumerable object):

  1. licznik ustawiony na 0.
  2. Get pierwszy element.
  3. Dodaj 1 do licznika.
  4. Przejdź do następnego elementu.
  5. Krok 3 aż do następnego elementu jest null
  6. Powrót Licznik

więc proponuję trochę przepisywanie.

Wariant 1:

  1. Tworzenie nie IEnumerable kolekcję, ale niektóre silniejsze obiektu, jak List lub Array:

    var milestones = viewModel.Milestones.ToArray();
    //var milestones = viewModel.Milestones.ToList();

    Po tym można użyć odpowiednio Count i Length właściwości dla Assert sprawdź:

    Assert.That(milestones.Count, Is.EqualTo(1));
    //Assert.That(milestones.Length, Is.EqualTo(1));

  2. Tworzenie zmiennej lokalnej przechowywać parametr Count:

    var count = viewModel.Milestones.Count(); // .Count() method executes here. Assert.That(count, Is.EqualTo(1));

+1

Rozumiem, co mówisz, i ma to jakiś sens. Ale wciąż mam pytanie, czy wywołanie 'parentViewModel' powinno zwracać prawdziwy obiekt' List <> '(zwróć uwagę na wywołanie' Expect'). Zatem wywołanie 'Count()' nie powinno nawet wymagać wyliczenia, powinno wywoływać właściwość Count na liście. To prawie tak, jakby RhinoMocks przepisał ponownie wartość zwracaną. – CodingGorilla

+1

@Coding Gorilla muszę pamiętać, że są wywołaniem '.Count()' 'sposobu IEnumerable ' ', a nie własność Count' z listy' ', więc to prowadzić do wyliczenie' 'IEnumerable . – VMAtm

+1

To nieprawda, metoda .Count() jest wystarczająco inteligentny, aby dowiedzieć się, czy leżących u podstaw typ obsługuje właściwości Count, i użyje tej nieruchomości, jeżeli jest ona dostępna. Patrz uwagi tutaj: http://msdn.microsoft.com/en-us/library/bb535181.aspx – CodingGorilla

Powiązane problemy