Clean Architecture use case testing

Use case interactors in the Clean Architecture consists of the application specific business rules.

Clean Architecture diagram

Interactors uses the Data Access Interface to fetch the required data from the data access layer.
Basically I see two approaches to test these interactors.

  • Using test doubles rather than the actual data access layer
  • Using the real data access layer (e.g. sql database, webservice)

I personally prefer the first approach and test the data access layer seperately.
The interactor tests uses the Data Access Interface with the test doubles and the entities in the inner circle.
An architectural boundary is crossed in both approaches.

Is the first test approach considered as Integration Testing with a narrower scope or is it just Unit Testing?

Go to Source
Author: Stefan

How to handle different types of errors in Clean Architecture?

So, in the process of creating a user there are 4 possible outcomes:

  1. Username is already taken

  2. Email is already taken

  3. Username is invalid
  4. Email is invalid

Here is what I have in the controller for now:

  const user = await this.addUserService.add(username, email, password)

  if (user) {
    return {
      statusCode: 201,
      body: user
    }
  } else {
    return {
      statusCode: 400,
      body: // ???
    }
  }

The thing is, what should the addUserService return if the username/email is invalid or in use?

I am thinking about creating different error types, such as InvalidParamsError, ParamInUseError and share them between the UserController and UserService.

So I would have something like this:

  const result = await this.addUserService.add(username, email, password)

  if (typeof result === InvalidParamsError || typeof result === ParamInUseError) {
    return {
      statusCode: 401,
      body: result.message
    }
  } else { // then we assume user has been created
    return {
      statusCode: 201,
      body: 'User created!'
    }
  }

Is it okay to share these Error classes between the controller and the service? If not, or even if it’s okay, is there a better way to handle errors when the outcome is not a simple true or false?

Thanks.

Go to Source
Author: kibe