我正在尝试模拟一个使用 JAXRS 的类,并且该类是一个 spring 组件。
@Component
public class PostmanClient {
private WebTarget target;
public PostmanClient() {
Client client = ClientBuilder.newClient();
target = client.target(...);
}
public String send(String xml) {
Builder requestBuilder = target.request(MediaType.APPLICATION_XML_TYPE);
Response response = requestBuilder.post(Entity.entity(xml, MediaType.APPLICATION_XML_TYPE));
return response.readEntity(String.class);
}
}
这是我的测试方法:
@Test
public void processPendingRegistersWithAutomaticSyncJob() throws Exception {
PostmanClient postmanClient = mock(PostmanClient.class);
String response = "OK";
whenNew(PostmanClient.class).withNoArguments().thenReturn(postmanClient);
when(postmanClient.send("blablabla")).thenReturn(response);
loadApplicationContext(); // applicationContext = new ClassPathXmlApplicationContext("/test-context.xml");
}
当我调试 postmanClient 实例时,它是由 Spring 创建的实例,而不是模拟。 我如何避免这种行为并获得模拟实例?
如果您将 PowerMock 与 Spring 一起使用,您应该考虑以下提示:
1.使用@RunWith(SpringJunit4Runner.class)
2. 使用 @ContextConfiguration("/test-context.xml") // 在测试之前加载 spring 上下文
3. 使用 @PrepareForTest(....class) // 模拟静态方法
4.使用PowerMockRule
5. 模拟 spring bean 最简单的方法是使用 springockito
回到你的问题:
如果我没理解错的话,你在 spring 上下文中定义了
PostmanClient
,这意味着,你只需要使用 springockito
来实现你的目标,只需按照 springockito 页面上的教程进行操作即可。
我不确定您的实施有什么问题。也许 PostmanClient 应该是一个接口而不是类?
但是我在我的实践/测试项目中实现了类似的单元测试。也许会有帮助:
在测试的构造函数中启动应用程序上下文之前,使用 Spring-ReInject 注册您的模拟。原来的bean将被替换为mock,并且该mock将被Spring到处使用,包括注入的字段。原始 bean 将永远不会被创建。
我创建了示例来回答另一个问题,但也涵盖了您的案例。通过
MockitoJUnitRunner
简单替换 SpringJUnit4ClassRunner
。
简而言之,我创建了 Java Spring 配置,其中仅包含应该测试/模拟的类,并返回模拟对象而不是真正的对象,然后让 Spring 让它工作。非常简单且灵活的解决方案。
它也可以与
MvcMock
配合使用。
从 Spring Boot 1.4.x 开始,您可以使用名为 @MockBean 的新注释。
您可以使用BDD框架Spock为您的Spring框架编写UT。使用 Spock Spring 扩展(Maven:groupId:org.spockframework,artifactId:spock-spring),您可以在单元测试中加载 Spring 上下文。
@WebAppConfiguration
@ContextConfiguration(classes = Application.class)
class MyServiceSpec extends Specification {
@Autowired
UserRepository userRepository
}
如果您有一些想要模拟它们而不是从 Spring 上下文加载的 bean,您可以在要模拟的 bean 上添加以下注释。
@ReplaceWithMock
这篇文章详细介绍了如何使用 Spock 为 Spring 应用程序编写 UT。