3

I've got these two lines on my code.

Customer customer = Repository.Customer.GetById(customerId);
Employee employee = customer.Employees.Single(e => e.IsPrimaryContact);

Now, I'm creating a unit test. Both Objects, customer and employee are protected so I need to mocked them.

I've successfully mocked the first one and created a mocked object 'customer' as its return for getting the customer By Id.

Customer customer = new Mock<Customer>().Object;
/* code ... code*/

var mockCustomerRepository = new Mock<ICustomerRepository>();
mockCustomerRepository.Setup(p => p.GetById(It.IsAny<Guid>())).Returns(customer);
Repository.Customer = mockCustomerRepository.Object;

As you can see, the 'employee' object is inside the mocked object 'customer' which means I also have to provide a mocked object inside my first mocked object (Customer). I'm expecting my code to be like this.

Employee employee = new Mock<Employee>().Object;
employee.IsPrimaryContact = true;

List<Employee> employees = new List<Employee>();
employees.Add(employee);

customer.Employees = employees;
/* code ... code*/

However, though I don't have any error on building my test. The customer.employee is ALWAYS NULL.

choopau
  • 2,209
  • 5
  • 21
  • 28

3 Answers3

3

I would suggest you to try this code

Mock<Customer>() mockCustomer = new Mock<Customer>();
Employee employee = new Employee();
mockCustomer.Setup(x=>x.Employees).Returns(employee);
Customer customer = mockCustomer.Object;
Sethu Bala
  • 457
  • 3
  • 17
2

The suggestion from Sethu Bala probably wont work because you cannot setup non virtual members.

Could you create Customer and Employee by calling constructor, builder or some tool like AutoFixure? And then setup your repository to returns those objects.

var customer = CustomerBulder
    .WithEmployees(*list of employees*)
    .Build();
var mockCustomerRepository = new Mock<ICustomerRepository>();
mockCustomerRepository
    .Setup(p => p.GetById(It.IsAny<Guid>()))
    .Returns(customer);
Johnny
  • 8,939
  • 2
  • 28
  • 33
2

Use the Linq to Mocks Mock.Of<T> to get the mocked object if no complex setup is needed. It will allow for assignment of property values.

Employee employee = Mock.Of<Employee>();
employee.IsPrimaryContact = true;

List<Employee> employees = new List<Employee>();
employees.Add(employee);

Customer customer = Mock.Of<Customer>();
customer.Employees = employees;

var mockCustomerRepository = new Mock<ICustomerRepository>();
mockCustomerRepository.Setup(p => p.GetById(It.IsAny<Guid>())).Returns(customer);
Repository.Customer = mockCustomerRepository.Object;

This should now exercise the unit test as expected.

Nkosi
  • 235,767
  • 35
  • 427
  • 472