Skip to content
Advertisement

What should I test in an application layer service

I wrote the following application service for a project I’m working on, but struggled to write a good unit test for it.

/**
 * @param ReleaseItemRequestDTO $request
 * @return AcknowledgmentResponseDTO
 * @throws CargoNotFound
 * @throws MissingRouteAccess
 * @throws MissingStaffPrivilege
 * @throws StaffNotFound
 * @throws WrongCargoReleaseCode
 */
public function execute(ReleaseItemRequestDTO $request): AcknowledgmentResponseDTO
{
    $releaseCode = ReleaseCode::from($request->releaseCode);
    $staffId = StaffEntityId::from($request->authenticatedStaffId);
    $staff = $this->staffRepository->findById($staffId);
    $cargo = $this->cargoRepository->findByReleaseCode($releaseCode);
    $staff->releaseCargo($cargo, $releaseCode);
    $this->cargoRepository->save($cargo);
    return new AcknowledgmentResponseDTO();
}

As you can see, the service itself doesn’t perform any meaningful logic other than orchestrating the domain layer (as it should if I understand correctly, according to the blue book).

What would be your suggestions to unit test such service ?

Advertisement

Answer

What would be your suggestions to unit test such service ?

Don’t.

Think about what benefits you expect to get from unit testing this code, then consider the different ways you might achieve those benefits, and the relative costs of each.

GeePaw Hill’s discussion of the TDD Value Premise suggests some good heuristics about what sorts of code deserve/require automated tests.

My preferred technique for “testing” this code would be to grab a second pair of eyes and review the code. Even a rubber duck might get the job done. Add a comment with the signature of the code reviewer(s) and the date, and move on to useful work.


Here’s a more extreme version

public function execute(ReleaseItemRequestDTO $request): AcknowledgmentResponseDTO {
    return executeV2($request, $this->cargoRepository, $this->staffRepository);
}

public function executev2(ReleaseItemRequestDTO $request, CargoRepository $cargoRepository, StaffRepository $staffRepository): AcknowledgmentResponseDTO {
{
    $releaseCode = ReleaseCode::from($request->releaseCode);
    $staffId = StaffEntityId::from($request->authenticatedStaffId);
    $staff = $staffRepository->findById($staffId);
    $cargo = $cargoRepository->findByReleaseCode($releaseCode);
    $staff->releaseCargo($cargo, $releaseCode);
    $cargoRepository->save($cargo);
    return new AcknowledgmentResponseDTO();
}

Riddle: does execute, in this case, need its own “unit tests”?

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement