Khiem Nguyen
Khiem Nguyen

Reputation: 413

Should I write unit test for controller or service layer or both of them?

I'm learning and trying use unit test for my project. But when I try write a demo with unit test I saw that unit test for controller same like for service layer. Below is unit test code I wrote for controller and service layer

Controller test:

  private Mock<ICountryService> _countryServiceMock;
  CountryController objController;
  List<Country> listCountry;

  [TestInitialize]
  public void Initialize()
  {

      _countryServiceMock = new Mock<ICountryService>();
      objController = new CountryController(_countryServiceMock.Object);
      listCountry = new List<Country>() {
       new Country() { Id = 1, Name = "US" },
       new Country() { Id = 2, Name = "India" },
       new Country() { Id = 3, Name = "Russia" }
      };
  }

  [TestMethod]
  public void Country_Get_All()
  {
      //Arrange
      _countryServiceMock.Setup(x => x.GetAll()).Returns(listCountry);

      //Act
      var result = ((objController.Index() as ViewResult).Model) as List<Country>;

      //Assert
      Assert.AreEqual(result.Count, 3);
      Assert.AreEqual("US", result[0].Name);
      Assert.AreEqual("India", result[1].Name);
      Assert.AreEqual("Russia", result[2].Name);

  }

Service test:

  private Mock<ICountryRepository> _mockRepository;
  private ICountryService _service;
  Mock<IUnitOfWork> _mockUnitWork;
  List<Country> listCountry;

  [TestInitialize]
  public void Initialize()
  {
      _mockRepository = new Mock<ICountryRepository>();
      _mockUnitWork = new Mock<IUnitOfWork>();
      _service = new CountryService(_mockUnitWork.Object, _mockRepository.Object);
      listCountry = new List<Country>() {
       new Country() { Id = 1, Name = "US" },
       new Country() { Id = 2, Name = "India" },
       new Country() { Id = 3, Name = "Russia" }
      };
  }

  [TestMethod]
  public void Country_Get_All()
  {
      //Arrange
      _mockRepository.Setup(x => x.GetAll()).Returns(listCountry);

      //Act
      List<Country> results = _service.GetAll() as List<Country>;

      //Assert
      Assert.IsNotNull(results);
      Assert.AreEqual(3, results.Count);
  }

Upvotes: 10

Views: 6017

Answers (1)

Jimmy Bogard
Jimmy Bogard

Reputation: 26765

At the controller level, I tend to write end-to-end tests. No mocks, no fakes, only the real things.

The reason is that in the test you have above, your unit test is coupled to the implementation details of your controller action. Suppose you no longer use a repository, or unit of work, your test would no longer even compile. At this level, you should be concerned about testing behavior, not implementation.

I unit test isolated domain models, integration test the rest.

Upvotes: 13

Related Questions