使用 Spring Boot 和 Mockito 模拟对象方法调用
Posted
技术标签:
【中文标题】使用 Spring Boot 和 Mockito 模拟对象方法调用【英文标题】:Mock object method call using Spring Boot and Mockito 【发布时间】:2015-12-25 13:13:12 【问题描述】:我正在尝试为这个 Java SpringBoot 的类编写一个测试:
https://github.com/callistaenterprise/blog-microservices/blob/master/microservices/composite/product-composite-service/src/main/java/se/callista/microservices/composite/product/service/ProductCompositeIntegration.java
具体来说,我正在尝试“模拟”这个方法调用:
URI uri = util.getServiceUrl("product");
我想我应该“模拟”ServiceUtils
对象才能做到这一点。我尝试使用@Mock
和@InjectMocks
注释:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ProductCompositeServiceApplication.class)
public class ProductCompositeIntegrationTest
@InjectMocks
@Autowired
private ProductCompositeIntegration productIntegration;
@Autowired
private RestTemplate restTemplate;
@Mock
private ServiceUtils util;
private MockRestServiceServer mockServer;
@Before
public void setUp()
MockitoAnnotations.initMocks(this);
mockServer = MockRestServiceServer.createServer(restTemplate);
@Test
public void myTest()
Mockito.when(util.getServiceUrl("product")).thenReturn(URI.create("http://localhost:8080/test"));
ResponseEntity<Iterable<Product>> products = productIntegration.getAllProducts();
但是这样它仍然调用原始的ServiceUtils
对象,而不是“模拟”对象。还尝试在ProductCompositeIntegration
处不使用@Autowired
注释,但这会导致NullPointerException
。
我做错了什么?
我的主课是这样的:
@SpringBootApplication
@EnableCircuitBreaker
@EnableDiscoveryClient
public class ProductCompositeServiceApplication
public static void main(String[] args)
SpringApplication.run(ProductCompositeServiceApplication.class, args);
我试图模拟的 ServiceUtils
对象在一个类中指定,并使用 Spring 的 @Component
注释进行注释,以使用 @Autowired
将其注入其他类。
【问题讨论】:
【参考方案1】:你必须写一个FactoryBean
喜欢
public class MockitoFactoryBean<T> implements FactoryBean<T>
private Class<T> classToBeMocked;
public MockitoFactoryBean(Class<T> classToBeMocked)
this.classToBeMocked = classToBeMocked;
@Override
public T getObject() throws Exception
return Mockito.mock(classToBeMocked);
@Override
public Class<?> getObjectType()
return classToBeMocked;
@Override
public boolean isSingleton()
return true;
在您的test-context.xml
中,您必须添加以下行。
<bean id="serviceUtilMock" class="MockitoFactoryBean">
<constructor-arg value="your.package.ServiceUtil" />
</bean>
如果你不使用 XML 配置,那么你必须在你的 Java 配置中添加上面的等价物。
【讨论】:
我必须对必须测试的类进行任何更改吗?我尝试使用这个工厂在 Test 类中实例化 ServiceUtils 对象,但结果是相同的 @Mock private ServiceUtils util = factoryBean.getObject(); 您必须在 test-context.xml 中添加 FactoryBean。我编辑了答案。【参考方案2】:经过多次反复试验,我设法解决了这个问题。
我放弃了
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ProductCompositeServiceApplication.class)
注释高于测试类。
我用@InjectMocks
标记了我正在测试的类,用@Mock
标记了依赖项:
public class ProductCompositeIntegrationTest
@InjectMocks
private ProductCompositeIntegration productIntegration;
@Mock
private ServiceUtils util;
private MockRestServiceServer mockServer;
private RestTemplate restTemplate = new RestTemplate();
@Before
public void init()
MockitoAnnotations.initMocks(this);
mockServer = MockRestServiceServer.createServer(restTemplate);
productIntegration.setRestTemplate(restTemplate);
@Test
public void someTests()
when(util.getServiceUrl("product")).thenReturn(URI.create("http://localhost:8080/test"));
//Test code...
我不确定这是否是最好的方法(“Spring 方式”),但这对我有用。
这篇文章让我明白了:http://rdafbn.blogspot.be/2014/01/testing-spring-components-with-mockito.html
【讨论】:
我喜欢你的方法。这正是我想要的。以上是关于使用 Spring Boot 和 Mockito 模拟对象方法调用的主要内容,如果未能解决你的问题,请参考以下文章
我需要在 Spring Boot 项目中使用 mockito
如何模拟 JWT 令牌以将其与 Mockito 和 Spring Boot 一起使用