Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock services inside another spring service with mockito

I'm facing problems mocking services injected inside of other services within the Spring framework. Here is my code:

@Service("productService")
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ClientService clientService;

    public void doSomething(Long clientId) {
        Client client = clientService.getById(clientId);
        // do something
    }
}

I want to mock the ClientService inside my test, so I tried the following:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/spring-config.xml" })
public class ProductServiceTest {

    @Autowired
    private ProductService productService;

    @Mock
    private ClientService clientService;

    @Test
    public void testDoSomething() throws Exception {
        when(clientService.getById(anyLong()))
                .thenReturn(this.generateClient());

        /* when I call this method, I want the clientService
         * inside productService to be the mock that one I mocked
         * in this test, but instead, it is injecting the Spring 
         * proxy version of clientService, not my mock.. :(
         */
        productService.doSomething(new Long(1));
    }

    @Before
    public void beforeTests() throws Exception {
        MockitoAnnotations.initMocks(this);
    }

    private Client generateClient() {
        Client client = new Client();
        client.setName("Foo");
        return client;
    }
}

The clientService inside productService is the Spring proxy version, not the mock that I want. Is it possible to do what I want with Mockito?

like image 578
br4zuca Avatar asked Sep 25 '13 11:09

br4zuca


4 Answers

I would like to suggest you annotate the Test target with @InjectMock

Currently

    @Autowired
    private ProductService productService;

    @Mock
    private ClientService clientService;

Change to

    @InjectMock
    private ProductService productService;

    @Mock
    private ClientService clientService;

incase you still have NullPointerException for the MockingService => you can use Mockito.any() as arguments. Hopefully, it will help you.

like image 101
infD Avatar answered Oct 18 '22 03:10

infD


You need to annotate ProductService with @InjectMocks:

@Autowired
@InjectMocks
private ProductService productService;

This will inject the ClientService mock into your ProductService.

like image 6
Debojit Saikia Avatar answered Nov 07 '22 20:11

Debojit Saikia


There are more ways to achieve this, the most easy way to do this will be don't use field injection, but setter injection which means you should have:

@Autowired
public void setClientService(ClientService clientService){...}

in your service class, then you can inject your mock to the service in test class:

@Before
public void setUp() throws Exception {
    productService.setClientService(mock);
}

important: If this is only a unit test, please consider don't use SpringJUnit4ClassRunner.class, but MockitoJunitRunner.class, so that you can also use field inject for your fields.

like image 1
Jaiwo99 Avatar answered Nov 07 '22 19:11

Jaiwo99


In addition to

@Autowired
@InjectMocks
private ProductService productService;

Add the following method

@Before
public void setup() {
    MockitoAnnotations.initMocks(this);
}
like image 1
Jacky1205 Avatar answered Nov 07 '22 18:11

Jacky1205