Search code examples
c#unit-testing.net-core

Should I make a private method public just for testing?


I have a C# service with two methods:

private IEnumerable<RowsBalance> GetUpdatedRowsBalance(IEnumerbale<OrderRows> rows)
{
    //Do something important I want to test
}

public void UpdateBalance(int orderId)
{
    //Gets order rows from database
    var rows = orderRepository.GetRows(orderId);

    //Get updated balance
    var updatedBalanceRows = GetUpdatedRowsBalance(rows);

    //Save updated balance to database
    orderRepository.SaveBalance(updatedBalanceRows);
}

The private method has the logic I need to test, what should I consider in order to make my code testable ?

I'm thinking about:

  • Make GetUpdatedRowsBalance public and test that. Is it ok to make something public that will never be called outside of testing ?
  • Separate the important business logic I need to test on a different class. Still ok but this is not going to be reused elsewhere.
  • Make the public method returns something I can assert like updatedBalanceRows. I don't really like returns something I don't need just for testing.

I'm note sure how to approach this scenario.


Solution

  • You could test it as it is.

    Just create your own version of orderRepository.

    Here's an example of a very crude API, alter to your preference (or use Moq if you are that way inclined).

    // The Test
    
    // Arrange
    var orderRepositoryDouble = new OrderRepositoryDouble();
    orderRepositoryDouble.Rows = someFakeRows;
    var sut = new Whatever(orderRepositoryDouble);
    
    // Act
    sut.UpdateBalance();
    
    // Assert
    var updatedRows = orderRepositoryDouble.UpdatedRows;
    
    // Whatever.
    
    // The test double
    class OrderRepositoryDouble : IRepo
    {
        public IEnumerable<OrderRows> Rows { get; set; }
        public GetRows(int orderId) => Rows;
    
        public IEnumerable<RowsBalance> UpdatedRows { get; set; }
    
        public void SaveBalance(IEnumerable<RowsBalance> r) =>
            UpdatedRows = r;
    }