Use Moq to verify if list within object is changed properly
I'm trying to add Moq to my tests in MSTest to test parts of my code.
The code i want to test which is not working is a piece of code that should filter data retreived by a service and pass this through. My co开发者_运维问答de is set up through the MVP Pattern and i have the following components. (i'm testing my presenter)
Service -> this service is retrieving a list of objects and putting this in a model (I'm using a Mock (Moq) to return values)
Model -> Entity object with some general properties and a list of documents
View -> The interface my usercontrol is implementing to talk to the presenter. this view is also mocked with moq.
Presenter -> object to retrieve the model from the service and assign this model to a property of the view.
in my first scenario that is working i just retrieve a model from the service and the presenter passes this to a property of the view.
//Setup AccountsPayableService Mock
_mockedDocumentService = new Mock<IDocumentService>();
DocumentModel<InvoiceDocumentRow> model = new DocumentModel<InvoiceDocumentRow>();
List<InvoiceDocumentRow> invoices = new List<InvoiceDocumentRow>();
InvoiceDocumentRow row = new InvoiceDocumentRow();
row.BillingMonth = DateTime.Now;
invoices.Add(row);
model.Documents = invoices;
_mockedDocumentService.Setup(service => service.GetInvoiceDocumentList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), _user)).Returns(model);
//Setup View Mock
_mockedView = new Mock<IInvoicesView>();
//Setup Presenter to be tested
_presenter = new FooPresenter(_mockedDocumentService.Object);
_presenter.SetView(_mockedView.Object);
//Act
//These events will make the presenter do the call to the service and assign this to the view property
_mockedView.Raise(view => view.Init += null, new EventArgs());
_mockedView.Raise(view => view.FirstLoad += null, new EventArgs());
//Assert
_mockedDocumentService.Verify(aps => aps.GetInvoiceDocumentList(from, changedTo, _user), Times.Once());
_mockedView.VerifySet(view => view.DocumentList = model);
This test runs and is working perfectly.
however i also have a case where the presenter should filter some of the results it got back from the service and assign a subset to the view. For some reason i can't get this to work.
in essential this is exactly the same test code except a different method on the presenter is used that retrieves data from the service, filters it and then passes it back to the view.
when i do an assert on the view property like i did before:
_mockedView.VerifySet(view => view.DocumentList.Documents = filteredModel.Documents);
i'm getting an error:
System.ArgumentException: Expression is not a property setter invocation.
What am i doing wrong?
This is not working cause the filteredModel.Documentos is in another context. Your view doesn't receive this, receive another list that came from some filtering method.
Changing a little your structure I'll suggest create extensions methods and obviously tests to them.
So you can simple put list.FilterByName("Billy");
So you will create something like:
public static IEnumerable<ObjectFromVdCruijsen> FilteredByNome(this IEnumerable<ObjectFromVdCruijsen> enumerable, string name){
if (!string.IsNullOrEmpty(name)){
enumerable = enumerable.Where(s => s.Name.ToUpperInvariant().Contains(name.ToUpperInvariant()));
}
return enumerable;
}
I found the solution to my own problem.
I replace the verifySet to a normal assert the _mockedviw.object so i'm using the stub to test instead of the mock and this is working perfectly. to use the stub functionality i used:
_mockedView.SetupAllProperties();
It's not possible to compare 2 different reference objects by default so i'm just checking the properties manually.
精彩评论