我面临着在Spring框架内模拟注入其他服务的服务的问题。这是我的代码:
@Service("productService")
public class ProductServiceImpl implements ProductService {
@Autowired
private ClientService clientService;
public void doSomething(Long clientId) {
Client client = clientService.getById(clientId);
// do something
}
}
我想在我的测试中嘲笑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;
}
}
clientService
里面productService
是Spring代理版本,而不是我想要的模拟。我可以用Mockito做我想做的事吗?
答案 0 :(得分:4)
您需要使用ProductService
注释@InjectMocks
:
@Autowired
@InjectMocks
private ProductService productService;
这会将ClientService
模拟注入您的ProductService
。
答案 1 :(得分:1)
有更多方法可以实现这一目标,最简单的方法是don't use field injection, but setter injection
,这意味着您应该:
@Autowired
public void setClientService(ClientService clientService){...}
在您的服务类中,然后您可以将模拟注入测试类中的服务:
@Before
public void setUp() throws Exception {
productService.setClientService(mock);
}
important:
如果这只是一项单元测试,请考虑不要使用SpringJUnit4ClassRunner.class
,而是MockitoJunitRunner.class
,这样您也可以使用字段注入。
答案 2 :(得分:1)
我建议您用 Test target
注释 @InjectMock
目前
@Autowired
private ProductService productService;
@Mock
private ClientService clientService;
改为
@InjectMock
private ProductService productService;
@Mock
private ClientService clientService;
如果你仍然有 MockingService 的 NullPointerException => 你可以使用 Mockito.any() 作为参数。 希望能帮到你。
答案 3 :(得分:0)
除了
@Autowired
@InjectMocks
private ProductService productService;
添加以下方法
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}