Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the benefits of mocking the dependencies in unit testing?

I am working on unit testing stuffs for my controller and service layers(C#,MVC). And I am using Moq dll for mocking the real/dependency objects in unit testing.

But I am little bit confuse regarding mocking the dependencies or real objects. Lets take a example of below unit test method :-

[TestMethod]
public void ShouldReturnDtosWhenCustomersFound_GetCustomers ()
{
    // Arrrange 
    var name = "ricky";
    var description = "this is the test";

    // setup mocked dal to return list of customers
    // when name and description passed to GetCustomers method
    _customerDalMock.Setup(d => d.GetCustomers(name, description)).Returns(_customerList);

    // Act
    List<CustomerDto> actual = _CustomerService.GetCustomers(name, description);

    // Assert
    Assert.IsNotNull(actual);
    Assert.IsTrue(actual.Any());

    // verify all setups of mocked dal were called by service
    _customerDalMock.VerifyAll();
}

In the above unit test method I am mocking the GetCustomers method and returning a customer list. Which is already defined. And looks like below:

List<Customer> _customerList = new List<Customer>
{
    new Customer { CustomerID = 1, Name="Mariya",Description="description"},
    new Customer { CustomerID = 2, Name="Soniya",Description="des"},
    new Customer { CustomerID = 3, Name="Bill",Description="my desc"},
    new Customer { CustomerID = 4, Name="jay",Description="test"},
};

And lets have a look on the Assertion of Customer mocked object and actual object Assertion :-

Assert.AreEqual(_customer.CustomerID, actual.CustomerID);
Assert.AreEqual(_customer.Name, actual.Name);
Assert.AreEqual(_customer.Description, actual.Description);

But here I am not understanding that it(above unit test) always work fine. Means we are just testing(in Assertion) which we passed or which we are returning(in mocking object). And we know that the real/actual object will always return which list or object that we passed.

So what is the meaning of doing unit testing or mocking here?

like image 595
Pawan Avatar asked Apr 01 '14 10:04

Pawan


2 Answers

The true purpose of mocking is to achieve true isolation.

Say you have a CustomerService class, that depends on a CustomerRepository. You write a few unit tests covering the features provided by CustomerService. They all pass.

A month later, a few changes were made, and suddenly your CustomerServices unit tests start failing - and you need to find where the problem is.

So you assume:

Because a unit test that tests CustomerServices is failing, the problem must be in that class!!

Right? Wrong! The problem could be either in CustomerServices or in any of its depencies, i.e., CustomerRepository. If any of its dependencies fail, chances are the class under test will fail too.

Now picture a huge chain of dependencies: A depends on B, B depends on C, ... Y depends on Z. If a fault is introduced in Z, all your unit tests will fail.

And that's why you need to isolate the class under test from its dependencies (may it be a domain object, a database connection, file resources, etc). You want to test a unit.

like image 148
dcastro Avatar answered Oct 26 '22 12:10

dcastro


Your example is too simplistic to show off the real benefit of mocking. That's because your logic under test isn't really doing much beyond returning some data.

But imagine as an example that your logic did something based on wall clock time, say scheduled some process every hour. In a situation like that, mocking the time source lets you actually unit test such logic so that your test doesn't have to run for hours, waiting for the time to pass.

like image 36
500 - Internal Server Error Avatar answered Oct 26 '22 10:10

500 - Internal Server Error