1

This question is a follow-up question to Clean Architecture use case testing.

Suppose the production code injects Use Case Interactor into the Input Boundary - that happens somewhere in the main component1. But now I want to test the Input Boundary/Output Boundary of the use case. I can only think of two ways to do this:

  1. Recreate the dependency injection setup at the beginning of the test - this forces the test to depend on Use Case Interactor.
  2. Depend on the main component for DI - this seems risky because the main component is volatile.

Is there a clean way to handle this situation?

1 Clean Architecture Chapter 26, Robert C Martin

2 Answers2

0

The input boundary is a simple abstraction to prevent the controller from knowing about the specific use case interactor. It doesn’t do anything, it simply invokes the interactor.

If your language supports generics, you can makes this a generic class. In your test, create a fake interactor and use that to test the generics.

Personally I use the Mediatr library (C#). All interactors implement an IRequestHandler interface and input data implements IRequest. Inject Mediatr into the controller, create a new request and call mediator.Send(request);. It doesn’t get much cleaner than that and because you can rely on a library you don’t even have to write and test the glue code yourself!

Rik D
  • 4,975
0

How can I manage dependency injection in test code?

The same way you manage it in production code.

Suppose the production code injects Use Case Interactor into the Input Boundary

Then production code is confused because you don't inject classes into interfaces.

But now I want to test the Input Boundary/Output Boundary of the use case

Stop that. Test behavior not structure. The boundaries do not hold behavior. They define the mini language that can be used to communicate across the boundary. Tests should use that same mini language to test what's across the boundary.

I think it would be best to test UseCaseInteractor directly, rather than throught the boundaries. @Brady Dean

Using UseCaseInteractor through the boundary is the direct way. Anything else is sneaking past the abstraction you're meant to use. Tests that sneak in the back door only prove that the back door works.

Is there a clean way to handle this situation?

Focus on the behavior you expect when you use the unit under test in the way it's meant to be used. Don't worry about isolation unless that's needed to make the unit's behavior deterministic and fast. Don't go sneaking around abstractions. And stop treating behaviorless structure code as something that needs to be tested.

candied_orange
  • 119,268