Rahul Dhammy
Rahul Dhammy

Reputation: 1

Unit testing private methods and using mock objects

The internet is flooded with pages saying that we should not write unit test cases for a private method. But I am not sure is it correct to say that we should completely ignore the private methods for unit test cases? I know they would be eventually tested if we test the main public method. But imagine my method which hits the database and populates the object from the dataset is contained, in a private method. If I want to use mock for my database I would have to write a unit test case for this method which would force me to make it public. How do I overcome such situations?

Since below is my public method if I write a unit test case for that it would hit the databse everytime. Which i want to avoid, because database is an external dependency which I always want to mock. The other problem with using DB is suppose I am hardcoding a sysid from my unit test case it would work till the time the sysid exists in db. When that record is deleted from db the test case becomes useless.

public Order RetrieveOrderAndOrderItem()
{
   DataSet ordersDS = new DataSet();
   Order obj = new Order();
   OrdersDb.RetrieveOrders(conKey,companySysId,userSysId,orderId,ordersDS);
   obj = populateObjFromDb(ordersDS,orderItemId, orderItemSubType);
   return obj;
}

 private Order populateObjFromDb(DataSet orders,int orderItemId, int orderItemSubType)
 {
    Order orderObj = new Order();
    orderObj.OrderId = Converters.DBInt(orders.Tables[0].Rows[0]["OrderId"]);
    return orderObj;           
 }

Upvotes: 0

Views: 516

Answers (1)

Wouter de Kort
Wouter de Kort

Reputation: 39888

Testing private methods depends too much on the implementation of the class. You are right in stating that you test a class through its public methods. If you have a private method that does a lot of work you should move it to its own class.

When you find yourself in a situation where you want to test a private method you should start thinking about your design.

In your example, why isn't the code that reads the database and populates your objects a separate class? The Single Responsibility principle states that a class should have only one single responsibility. This new class could be injected into the original class, hereby following the Dependency Inversion principle.

The goal of things like TDD and Unit Testing is to arrive at a solution that follows the SOLID principles.

Upvotes: 4

Related Questions