Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSubstitute mock a void method with out parameters

I am new to NSubstitute, I am trying to mock a void method with 2 out parameters and I am pretty sure I am doing it wrong.

I have a CustomerDataAccess class that has a method with the following signature:

void GetCustomerWithAddresses(int customerId, 
                              out List<Customer> customers, 
                              out List<Address> addresses);

The CustomerRepository calls its GetCustomer method which then calls the CustomerDataAccess.GetCustomerWithAddresses DAL method. The DAL method then outputs two out parameters one for the customer and one for addresses. The repository method then uses AutoMapper to map the two objects from the DAL method to a business domain which the repository then returns.

Here is the code I have so far and it is not working. My research hasn't helped me to identify what I need to do to fix this issue. How do I set the value of my out parameters?

// Arange
ICustomerDataAccess customerDataAccess = Substitute.For<ICustomerDataAccess>();
IList<Customer> customers;
IList<Address> addresses;

customerDataAccess.When(x => x.GetCustomerWithAddresses(
    1, out customers, out addresses))
    .Do(x =>
    {
        customers = new List<Customer>() { new Customer() { CustomerId = 1, CustomerName = "John Doe" } };
        addresses = new List<Address>() { new Address() { AddressId = 1, AddressLine1 = "123 Main St", City = "Atlanta" } };
    });

CustomerRepository sut = new CustomerRepository(customerDataAccess);

// Act
Customer customer = sut.GetCustomer(1);

// Assert
Assert.IsNotNull(customer);
like image 596
NathanFisherSdk Avatar asked May 19 '15 15:05

NathanFisherSdk


2 Answers

out parameters are updated using their parameter position as an index. It's explained in the Returns documentation for NSubstitute. So, for your particular case, you are populating the second and third parameters, so you should be setting up your call like this:

customerDataAccess.When(x => x.GetCustomerWithAddresses(1, out customers, out addresses))
.Do(x =>
{
    x[1] = new List<Customer>() { new Customer() { CustomerId = 1, CustomerName = "John Doe" } };
    x[2] = new List<Address>() { new Address() { AddressId = 1, AddressLine1 = "123 Main St", City = "Atlanta" } };
});
like image 105
forsvarir Avatar answered Sep 20 '22 11:09

forsvarir


For non-void methods the regular return syntax can be used:

 var haveWithAddresses = customerDataAccess.GetCustomerWithAddresses(1, out customers, out addresses)
               .Returns(callInfo => { 
                     callInfo[0] = new List<Customer>();
                     callInfo[1] = new List<Address>();
                     return true;
               });

With Void methods the When...Do syntax is correct.

like image 23
Josh Gust Avatar answered Sep 17 '22 11:09

Josh Gust