Java 使用mockito在另一个spring服务中模拟服务
在Spring框架中,我面临着模拟注入到其他服务中的服务的问题。这是我的密码:Java 使用mockito在另一个spring服务中模拟服务,java,spring,junit4,mockito,spring-test,Java,Spring,Junit4,Mockito,Spring Test,在Spring框架中,我面临着模拟注入到其他服务中的服务的问题。这是我的密码: @Service("productService") public class ProductServiceImpl implements ProductService { @Autowired private ClientService clientService; public void doSomething(Long clientId) { Client clien
@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;
}
}
productService
中的clientService
是Spring代理版本,而不是我想要的模拟版本。有可能用Mockito实现我想要的吗?有更多的方法来实现这一点,最简单的方法是不要使用字段注入,而使用setter注入
,这意味着您应该:
@Autowired
public void setClientService(ClientService clientService){...}
在服务类中,您可以将模拟注入测试类中的服务:
@Before
public void setUp() throws Exception {
productService.setClientService(mock);
}
<代码>重要:如果这只是一个单元测试,请考虑不要使用<代码> SpRunJuniT4CaseRun.class < /C> >,但是<代码> MockitoJunitRunner .class < /C> >,这样您也可以为字段使用字段注入。 您需要用
@InjectMocks
注释ProductService
:
@Autowired
@InjectMocks
private ProductService productService;
这将把ClientService
mock注入到您的ProductService
中
@Autowired
@InjectMocks
private ProductService productService;
添加以下方法
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
我建议您使用
@InjectMock
目前
@Autowired
private ProductService productService;
@Mock
private ClientService clientService;
改为
@InjectMock
private ProductService productService;
@Mock
private ClientService clientService;
如果MockingService=>仍有NullPointerException,则可以使用Mockito.any()作为参数。
希望它能对你有所帮助。谢谢Debojit,但我意识到没有办法将spring的注入与mockito的模拟注入结合使用。。。因此,我的解决方案是手动创建ProductService,并像您所说的那样使用
@InjectMocks
注入mock,但不使用@Autowired
:@InjectMocks private ProductService ProductService=new ProductServiceImpl()代码>这很奇怪。我一直在同时使用这两个注释。你测试过了吗。同时使用这两个组件时是否有任何异常。是的,我对它进行了大量测试,即使使用ProductService上的@InjectMocks
,其中的clientService也是使用spring代理而不是模拟对象加载的。也许你正在使用的spring测试版本与我正在使用的不同,我的版本是3.0.1.RELEASE,你的版本是什么?我正在使用3.1.2.RELEASE和mockito 1.9.5,我改为3.1.2-RELEASE,得到了相同的结果。。。也许您的配置在某些方面与我的不同,好吧,无论如何,谢谢,因为现在我将使用手动实例化方法。谢谢,我尝试了该解决方案,效果很好,但我无法在该服务中更改为setter injection,因此我的解决方案是删除测试中的自动连线注释并手动创建服务,如下所示:@InjectMocks private-ProductService-ProductService=new-productserviceinpl()
@br4zuca您可以使用@InjectMocks private-ProductService-ProductService-ProductService
,不要初始化它的手册,让mockito来做。我尝试使用@InjectMocks
将mockito初始化为产品服务
,但没有工作,因为产品服务
是一个接口,它抛出:org.mockito.exceptions.base.MockitoException:type'ProductService'是一个接口
,因此它无法实例化。我找到了一个解决方案,而不是声明@InjectMock ProductService ProductService
,我将ProductService
接口更改为impl likeproductserviceinpl
,然后在这种形式下,mockito能够自动初始化我的服务,比如:@InjectMock-productserviceinpl-productService