3

I am new to unit testing and I want to create a test for my search feature. My service layer looks something like:

public class EmployeeService: BaseService, IEmployeeService
{
    public EmployeeService(IUnitOfWork unitOfWork) : base(unitOfWork)
    {
        _employeeRepo = unitOfWork.EmployeeRepository;
    }

    public IEnumerable<Employee> Search(Employee advancedSearch, int[] divisionIds, bool showInactive, int pageSize, int? page)
    {
        return _employeeRepo.Search(advancedSearch, divisionIds, showInactive, pageSize, page);
    }
}

Unit Test:

[Test]
public void SearchShouldFilterActiveEmployees()
{
    var employees = new List<Employee>
    {
        new Employee { EmployeeId = 105, FirstName = "John", LastName = "Smith", IsActive = true },
        new Employee { EmployeeId = 162, FirstName = "John", LastName = "Doe", IsActive = true },
        new Employee { EmployeeId = 3, FirstName = "Jan", LastName = "Doe", IsActive = true }
    };

    var mockUnitOfWork = new Mock<IUnitOfWork>();

    var sut = new EmployeeService(mockUnitOfWork.Object);

    var employeeSearchCriteria = new Employee
    {
        FirstName = "John"
    };

    var employeesReturned = sut.Search(employeeSearchCriteria, null, false, 25, 1);

    Assert.IsTrue(employeesReturned.Count() == 2);
}

I think the issue is with mocking the UnitOfWork. I am getting a Null Reference Exception. How can I moq the UnitOfWork so I can test that the correct number of employees is being returned from the Search.

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
Andrew
  • 2,013
  • 1
  • 23
  • 38
  • You'll need to mock `EmployeeRepository` and `Search` in particular... as side effect your test would be adding less value than you expect since there will be no real filtering provided database access is faked – Claudio Redi Oct 05 '15 at 19:25
  • Do you think there would be any point to creating this test? In my repository tests I already created a test similar to this except the `System Under Test` would be the `EmployeeRepository` and not the `EmployeeService`. I really just want to test that my service layer can call the `Search` method in my repository. – Andrew Oct 05 '15 at 19:29
  • make sense to test it, it's not the most probably point of failure since there is basically no logic but you can test that you call `Search` with correct parameters. Create a setup to return 2 employees only when `Search` is called with correct parameters. If incorrect parameters are used, `Search` will return null and your assert will fail – Claudio Redi Oct 05 '15 at 20:15

1 Answers1

5

For mocking the repository it would be the easiest to create an interface for it, e.g. IEmployeeRepo. Then in the EmployeeService class the field would be private readonly IEmployeeRepo _employeeRepo.

In the test you could then verify that Search was called.

bool searchwasCalled = false;
Mock<IEmployeeRepo> repositoryMock = new Mock<IEmployeeRepo>();
repositoryMock.Setup(r => r.Search(
    It.IsAny<Employee>(), It.IsAny<int[]>(), It.IsAny<bool>(), It.IsAny<int>(),
    It.IsAny<int?>()))
    .Callback(() => searchwasCalled = true);

var mockUnitOfWork = new Mock<IUnitOfWork>();
mockUnitOfWork.Setup(uow => uow.EmployeeRepository).Returns(repositoryMock.Object);

var sut = new EmployeeService(mockUnitOfWork.Object);

var employeeSearchCriteria = new Employee
{
    FirstName = "John"
};

sut.Search(employeeSearchCriteria, null, false, 25, 1);

Assert.IsTrue(searchwasCalled, "Search was not called.");  
Daniel Dušek
  • 13,683
  • 5
  • 36
  • 51