Search code examples
c#.netunit-testingmockingrhino-mocks

How to mock data access in private methods


I would like to ask how can I use rhino mocks with in the next example:

   Public Class CustomerService 
    {
      Public void Register()
     {
         Action1();
         Action2();
     }

    private action1 ()
     {
       //this is a call to other dll.
       var isExist = _dataComponentService.CheckIfUserExist(userName);
     } 
   private action2()
     {
       //do some more work...
       // Call to dataComponentService. write some data in the database....
     }
    }

this is only an example for the real code I need to update. The current unit tests are making a real call to the database service. I would like to write a unit tests that checks the behavior in the public Register() with out needing to make a real call to the database service.

is it possible to mock a call to other component that is located in private method without needing to re-write the hole service?

thank you in advanced

Ori


Solution

  • You'll need to do some dependency injection to get your mock into your class-under-test (for more information on DI, check out this article by Martin Fowler). First your 'dataComponentService' class will need to implement an interface:

    public interface IDataComponentService
    {
        boolean CheckIfUserExist(String user);
    }
    

    Then you can inject classes that implement that interface into your CustomerService class by adding an appropriate constructor:

    public class CustomerService 
    {
        private IDataComponentService _dataComponentService
    
        // This constructor allows you to inject your dependency into the class
        public CustomerService(IDataComponentService dataComponentService)
        {
            _dataComponentService = dataComponentService;
        }
    
        Public void Register()
        {
            Action1();
            Action2();
        }
    
        private action1 ()
        {
            //this is a call to other dll.
            var isExist = _dataComponentService.CheckIfUserExist(userName);
        } 
    
        private action2()
        {
           //do some more work...
           // Call to dataComponentService. write some data in the database....
        }
    }
    

    Now, in your test code your tests you can create a mock of an IDataComponentService...

    var dataComponentServiceMock = MockRepository.GenerateMock<IDataComponentService>(); 
    //add mock's behavior here...
    

    ... and pass it into your class-under-test thus...

    var objUt = new CustomerService(dataComponentServiceMock);
    objUt.Register();
    // check method calls to the mock here...