1
votes

i am trying to inject a mock to be used by a service class that i am testing but the mock does not seem to be used.

public class SpringDataJPARepo{ public void someMethod();// my repo }

i have a service class that i wish to test

  @Service
  public class Service implements IService{

  @Autowired 
  private SpringDataJPARepo repository;

  public String someMethod(){ // repository instance used here }
  }

and i try to write my test cases by mocking the repository and injecting them into the service

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={ServiceTestConfiguration.class})
public class Test{

@Mock
private SpringDataJPARepo repository;

@Autowired
@InjectMocks
private IService service;

@Before
public void setup(){
MockitoAnnotations.initMocks(this);
when(repository.someMethod()).thenReturn("test");
}

@Test
public testSomeMethod(){
assertThat(service.someMethod()).isNotNull;
verify(repository.someMethod,atLeast(1)); //fails here
}

}

it throws a

Wanted but not invoked

in the verify method

i am not sure on how to inject the mock into the autowired instance. can anyone point out what i am doing wrong here?

2
Is your Service or its methods having any Spring annotations besides "@Service" such as "@Transactional" or "@Secured"? - uncaught_exception
no it does not have any other annotations - austin
Does your service class have any other dependencies other than SpringDataJPARepo ? - Bunti
yes, a few other Spring data repositories and another service class. - austin
Could you check what this displays in your test method: (AopUtils.isAopProxy(service) && service instanceof Advised) - uncaught_exception

2 Answers

2
votes

Try this [I will delete the answer if it does not work - can't put this in a comment]

public class TestUtils {

    /**
     * Unwrap a bean if it is wrapped in an AOP proxy.
     * 
     * @param bean
     *            the proxy or bean.
     *            
     * @return the bean itself if not wrapped in a proxy or the bean wrapped in the proxy.
     */
    public static Object unwrapProxy(Object bean) {
        if (AopUtils.isAopProxy(bean) && bean instanceof Advised) {
            Advised advised = (Advised) bean;
            try {
                bean = advised.getTargetSource().getTarget();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return bean;
    }

    /**
     * Sets a mock in a bean wrapped in a proxy or directly in the bean if there is no proxy.
     * 
     * @param bean
     *            bean itself or a proxy
     * @param mockName
     *            name of the mock variable
     * @param mockValue
     *            reference to the mock
     */
    public static void setMockToProxy(Object bean, String mockName, Object mockValue) {
        ReflectionTestUtils.setField(unwrapProxy(bean), mockName, mockValue);
    }
}

In @Before insert

TestUtils.setMockToProxy(service, "repository", repository);
0
votes

the problem was i was trying to inject the mocks into the interface variable and the interface did not have any reference variables.
i replaced it with a concrete implementation reference which has reference variables for the inject mocks and it works well

@InjectMocks
private Service service=new Service();