loading...

How to avoid mocking repository for Unit Tests

sam_ferree profile image Sam Ferree ・1 min read

I commonly see code written like this, even in courses.

public class DeskBookingProcessor
{
  public readonly IBookingRepository _bookingRepository;
  public readonly int _capacity;

  public async Task<Booking?> Book(BookingRequest request)
  {
    var currentBookings = await _bookRepository.GetBookingsAsync(request.Date);
    if (currentBookings + 1 > _capacity)
    {
      return null;
    }
    else
    {
      var booking = new Booking(request);
      await _bookingRepository.SaveAsync(booking);
      return booking;
    }
  }
}

The drawback is you have to mock a whole IBookingRepository (Even the methods this feature doesn't use) to test your booking logic.

Alternatively, you could do this

public class BookingAgent
{
  public Booking? Book(BookingRequest request, int currentBookings, int capacity) =>
    currentBookings + 1 > capacity
      ? null
      : new Booking(request);
}
public class DeskBookingProcessor
{
  public readonly IBookingRepository _bookingRepository;
  public readonly int _capacity;

  public async Task<Booking?> Book(BookingRequest request)
  {
    // Impure Collect
    var currentBookings = await _bookRepository.GetBookingsAsync(request.Date);
    var agent = new BookingAgent();

    // Pure Calculation
    var booking = agent.Book(request, currentBookings.Count(), capacity);

    // Impure Commit
    if (booking != null) await _bookRepository.SaveBookingAsync(booking);

    return booking;
  }
}

Now your unit tests don't need to mock impure dependencies, just test the BookingAgent by passing the parameters.

Leave it to your integration tests flex the combination of the pure logic and impure dependencies. Prefer the kind that stand up a whole test server and send HTTP requests and check HTTP responses.

That is all.

Posted on by:

sam_ferree profile

Sam Ferree

@sam_ferree

Full Stack Web Engineer Specializing in the C#, .NET Core, Angular, and Azure. But I've been lucky enough to dabble in Ruby, Python, Node.js, JAVA, C/C++, and more.

Discussion

markdown guide