2017-08-03 3 views
2

Ich arbeite derzeit mit Moq, um einige Komponententests durchzuführen. Ich stoße auf ein Problem, bei dem ich feststelle, was mein verspottetes Objekt zurückgibt, aber der eigentliche Aufruf gibt NULL zurück, anstatt dem, was ich in .Returns(...) spezifiziere. Ich habe andere Beiträge überprüft und einer der Vorschläge war, die Mock mit MockBehavior.Strict zu schaffen - nachdem dies zu tun, ich habe eine ziemlich ausführliche Fehlermeldung erhalten, wie folgt:MOQ'd-Objekt, das trotz Angabe von .Returns null zurückgibt

IMyRepository.Save(MvcIndividualAuth.Data.Models.DTO.MyTableDTO) invocation failed with mock behavior Strict. All invocations on the mock must have a corresponding setup.

aber ich rufe Setup auf das nur Methode, die mein verspottetes Objekt bereits aufruft. Bitte beachten Sie folgenden Code:

Mein Test:

MyService _myService; 
    Mock<IMyRepository> _myRepoMock; 

    [TestInitialize] 
    public void Setup() 
    { 
     _myRepoMock = new Mock<IMyRepository>(); 
     _myService = new MyService(_myRepoMock.Object); 
    } 

[TestMethod] 
    public void MyServiceSave() 
    { 
     //Arrange 
     var myDto = new MyTableDTO { Id = 1, Bar = 5, Foo = "Test" }; 
     _myRepoMock.Setup(x => x.Save(myDto)).Returns(myDto); 

     //Act 
     var vm = _myService.Save(new MyTableViewModel(myDto)); 

     //Assert 
     Assert.AreEqual(vm.Id, 1); 
     Assert.AreEqual(vm.Foo, "Test"); 
     Assert.AreEqual(vm.Bar, 5); 
     Assert.AreEqual(vm.BarPlusFoo, "5 Test"); 
    } 

MyService.Save Methode:

public MyTableViewModel Save(MyTableViewModel viewModel) 
    { 
     var dto = MyTableViewModel.GetDto(viewModel); 
     var dbDto = _myRepo.Save(dto); //_myRepo is of type IMyRepository, 
             // this _myRepo.Save call is returning null 

     var vm = new MyTableViewModel(dbDto); 

     return vm; 
    } 

Warum ist die verspottete Repo in meinem Test nicht den Wert der Rückkehr ich in meinem .Returns(..) Anruf angeben? Alle Hilfe wird geschätzt.

EDIT: wie gewünscht, hier ist MyRepository.Save Methode und MyTableViewModel.GetDto():

MyRepository.Save:

public MyTableDTO Save(MyTableDTO dto) 
    { 
     try 
     { 
     var entity = new MyTable(); 

     if (String.IsNullOrEmpty(dto.Foo)) 
     { 
      throw new ArgumentException("MyTable requires Foo"); 
     } 

     if (dto.Id == 0) 
     { 
      //added 
      entity.Update(dto); 
      _db.MyTables.Add(entity); 
     } 
     else 
     { 
      //modified 
      entity = _db.MyTables.Single(x => x.Id == dto.Id); 

      entity.Update(dto); 
     } 

     _db.SaveChanges(); 

     return new MyTableDTO(entity); 
     } 
     catch (Exception) 
     { 
     throw; 
     } 
    } 

MyTableViewModel.GetDto (..);

public static MyTableDTO GetDto(MyTableViewModel vm) 
    { 
     var dto = new MyTableDTO 
     { 
     Bar = vm.Bar, 
     Foo = vm.Foo, 
     Id = vm.Id 
     }; 

     return dto; 
    } 
+0

Könnten Sie 'Repository.Save zeigen()' Methode ? –

+0

Bitte geben Sie den Quellcode für 'GetDto' an. – mjwills

+0

@RomaDoskoch aktualisiert, um die angeforderten – GregH

Antwort

3

Sie erhalten null weil GetDto() kehrt anderes Objekt aus myDto - Referenzen unterschiedlich sind.

Sie können Ihre Setup() ändern myDto zurückzukehren:

_myRepoMock.Setup(x => x.Save(It.IsAny<MyTableDTO>())).Returns(myDto); 

Oder wenn Sie möchten Objekt zurückgeben, die als Parameter übergeben wurde:

_myRepoMock.Setup(x => x.Save(It.IsAny<MyTableDTO>())).Returns((MyTableDTO dto) => dto); 

Oder wenn Sie auf einige verspotten Basis Eigenschaften:

_myRepoMock.Setup(x => x.Save(It.Is<MyTableDTO>(dto => dto.Id == 1))).Returns(myDto); 

Oder wenn Sie die Rückgabe ändern möchten Ergebnis:

_myRepoMock.Setup(x => x.Save(It.IsAny<MyTableDTO>())).Returns((MyTableDTO dto) => { dto.Id = 2; return dto;}); 

Sie können auch alle Ansätze kombinieren.

2

Die MyTableDTO zurück von GetDTO ist ein neues MyTableDTO, die in ihrem Setup nicht das gleiche wie die Regel ist, weil sie eine andere Referenz hat, daher gibt es keine passende Setup für Save.

Stattdessen können Sie versuchen, so etwas wie:

_myRepo.Setup(s => s.Save(It.Is<MyTableDTO>(d => d.Equals(myDto))).Returns(myDto); 

Oder, wenn Sie über die genauen Werte Save bestanden nicht betroffen sind:

_myRepo.Setup(s => s.Save(It.IsAny<MyTableDTO>()).Returns(myDto); 
Verwandte Themen