Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to inject mocked Spring @Autowired dependencies from a unit test?

import org.springframework.beans.factory.annotation.Autowired;

class MyService {
  @Autowired private DependencyOne dependencyOne;
  @Autowired private DependencyTwo dependencyTwo;

  public void doSomething(){
    //Does something with dependencies
  }
}

When testing this class, I basically have four ways to inject mock dependencies:

  1. Use Spring's ReflectionTestUtils in the test to inject the dependencies
  2. Add a constructor to MyService
  3. Add setter methods to MyService
  4. Relax the dependency visibility to package-protected and set the fields directly

Which is the best and why?

--- UPDATE ---

I guess I should have been a bit clearer - I am only talking about "unit" style tests, not Spring "integration" style tests where dependencies can be wired in using a Spring context.

like image 808
Daniel Alexiuc Avatar asked Jul 27 '11 07:07

Daniel Alexiuc


People also ask

Which is the best dependency injection in Spring?

Setter Injection is the preferred choice when a number of dependencies to be injected is a lot more than normal, if some of those arguments are optional than using a Builder design pattern is also a good option. In Summary, both Setter Injection and Constructor Injection have their own advantages and disadvantages.

Which annotation can be used for injecting dependencies in Spring?

@Autowired annotation is used to let Spring know that autowiring is required. This can be applied to field, constructor and methods. This annotation allows us to implement constructor-based, field-based or method-based dependency injection in our components.


1 Answers

Use ReflectionTestUtils or put a setter. Either is fine. Adding constructors can have side effects (disallow subclassing by CGLIB for example), and relaxing the visibility just for the sake of testing is not a good approach.

like image 138
Bozho Avatar answered Sep 20 '22 15:09

Bozho