Dago
Dago

Reputation: 808

@InjectMocks not working while Autowiring rest of dependencies

I am trying to test a ClassA which uses 2 services. One service needs to be autowired and one to be treated as mocked object instead. Unfortunately mocked object is

not injected

to my tested class. All fields are behaving like I would only use spring autowiring feauture to set it up. Tested ClassA is inheriting from other abstract class also. If no autowiring is used, mocked object is passed succesfully. Unfortunately I can't mocked ServiceDao, thats why I am trying to combine @InjectMocks and @Autowiring annotation.

Class A.

public ClassA extends AbstractClassA<ClassOne, ClassTwo>{

   @Autowired
   protected ServiceOne serviceOne;      //this services needs to be mocked

   @Override
   protected List<ClassTwo> testedMethod(){
      return serviceOne.getList();      //here method is not returning mocked objects 
   }                                    //as it supposed to do.
     ........
}

AbstractClass

public class AbstractClassA<T1 extends InterfaceOne, T2 extends InterfaceTwo){
    @Autowired
    protected ServiceDAO serviceDAO; //this services needs to be autowired

    protected abstract List<T2> testedMethod();

}

TestClass.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:testApplicationContext.xml"})
public class Test {
    @Mock
    private ServiceOne serviceOne; //this mock object and it's return
                                   //objects are set properly


    @Autowired
    @InjectMocks
    private ClassA classA;  //all fields are autowired, including the services that should be mocked

    @Before
    public void setData(){
       Mockito.Annotations.initMocks(this);
       List<ClassTwo> result = Arrays.asList(new ClassA());
       when(serviceOne.testedMethod().thenReturn(result); //here when i invoke mocked object it is returning correct list.  
  }
}

Upvotes: 3

Views: 5893

Answers (1)

Xantier
Xantier

Reputation: 306

In this case it's probably best to mock the injected bean via your Spring test context configuration. If you are not able to do that easily, you can using Springs ReflectionTestUtils class to mock individual objects in your service.

In your test configuration XML file you can define a mocked bean:

<bean id="serviceOne" class="org.mockito.Mockito" factory-method="mock"/>
    <constructor-arg value="com.package.ServiceOne"/>
</bean>

In Java side:

@Bean
public ServiceOne serviceOne() {
    return mock(ServiceOne.class);
}

In your test case you can @Autowire ServiceOne serviceOne and use that as your mock object:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:testApplicationContext.xml"})
public class Test {
    @Autowired
    private ServiceOne serviceOne; 

    @Autowired
    private ClassA classA; 

    @Before
    public void setData(){
       Mockito.Annotations.initMocks(this);
       List<ClassTwo> result = Arrays.asList(new ClassA());
       when(serviceOne.testedMethod()).thenReturn(result);
  }
}

Upvotes: 6

Related Questions