Mockito can't inject mocks

David Antelo :

I'm using Mockito and I'm trying to inject a Mock CustomFileHandler into my REjercicioDAO class for testing purposes. The thing is, my test throws no exceptions, but it doesn't inject my mock object, the original @Autowired CustomFileHandler is not being substituted. Here's my code:

@Repository
public class REjercicioDAO extends ARHibernateDAO < REjercicio > implements IREjercicioDAO {

    @Autowired
    public ICustomFileHandler customFileHandler;

    ...

}

And here's my test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = ATest.CONTEXT_CONFIGURATION)
public class REjercicioDAOTest extends ATest {

    @Mock private ICustomFileHandler customFileHandler;

    @Autowired
    @InjectMocks
    private IREjercicioDAO rEjercicioDAO;

    @Before
    public void before () {

        MockitoAnnotations.initMocks(this);

        ...

    }

Btw, entities work as expected and interfaces are correctly linked to the actual entities, I have tested that. How can I fix this?

davidxxx :

Here is a no answer. I could not give more because I am really sorry to see so many people use this awkward API relying on reflection while you could do things really clear for the readers of the class by explicitly setting the dependency.

The thing is, my test throws no exceptions, but it doesn't inject my mock object

Not surprising. This way of injecting the mock stays quiet even if no injection succeeds. From the InjectMocks javadoc (emphasis is not mine!) :

Mockito will try to inject mocks only either by constructor injection, setter injection, or property injection in order and as described below. If any of the following strategy fail, then Mockito won't report failure; i.e. you will have to provide dependencies yourself.

While Mockito does not report failure, I really discourage to use this API.

About your actual issue, look at that :

@Autowired
@InjectMocks
private IREjercicioDAO rEjercicioDAO;

You annotate the field with both Spring and Mockito annotation. Do you feel confortable with the order of their processing ? These come from two distinct libraries. I don't tell that it will never work (luck and random exists) but do you really think that it is robust ?

To achieve your requirement you could write something like that that does things in two explicit steps :
- objects instantiation : mocking the dependency and inject the spring dependency
- relationship set : between the mock dependency and the spring dependency

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = ATest.CONTEXT_CONFIGURATION)
public class REjercicioDAOTest extends ATest {

    @Mock 
    private ICustomFileHandler customFileHandler;

    @Autowired        
    private IREjercicioDAO rEjercicioDAO;

    @Before
    public void before () {    
        MockitoAnnotations.initMocks(this);
        // Set explicitly the fileHandler dependency
        rEjercicioDAO.setFileHandler(customFileHandler);         
    }
 }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=311183&siteId=1