[英]Mock services inside another spring service with mockito
I'm facing problems mocking services injected inside of other services within the Spring framework.我在模拟 Spring 框架内其他服务中注入的服务时遇到了问题。 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:我想在我的测试中模拟
ClientService
,所以我尝试了以下操作:
@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. productService
里面的clientService
是Spring代理版本,不是我想要的mock。 Is it possible to do what I want with Mockito?可以用 Mockito 做我想做的事吗?
You need to annotate ProductService
with @InjectMocks
:您需要使用
@InjectMocks
注释ProductService
:
@Autowired
@InjectMocks
private ProductService productService;
This will inject the ClientService
mock into your ProductService
.这会将
ClientService
模拟注入您的ProductService
。
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:有更多方法可以实现这一点,最简单的方法是
don't use field injection, but setter injection
,这意味着您应该拥有:
@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. important:
如果这只是一个单元测试,请考虑不要使用SpringJUnit4ClassRunner.class
,而是MockitoJunitRunner.class
,以便您也可以为您的字段使用字段注入。
In addition to除了
@Autowired
@InjectMocks
private ProductService productService;
Add the following method添加以下方法
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
I would like to suggest you annotate the Test target
with @InjectMock
我建议您使用
@InjectMock
注释Test target
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.如果你仍然有 MockingService 的 NullPointerException => 你可以使用 Mockito.any() 作为参数。 Hopefully, it will help you.
希望它会帮助你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.