使用SpringBoot集成Jersey做单元测试时遇到了application.xml找不到的提示。详情如下:
Caused by: java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be opened because it does not exist at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:172) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:330) ... 61 more
测试使用的代码大致如下:
import com.zhyea.jspy.QueryServiceApplication;
import com.zhyea.jspy.bean.Probe;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.ws.rs.core.Application;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = MySpringApplication.class)
public class MyResourceTest extends JerseyTest {
@Override
protected Application configure() {
return new ResourceConfig(MyResource.class);
}
@Test
public void testGet() {
final Probe p = target("/api/probe/get/106").request().get(Probe.class);
System.out.println(p);
}
}
原因是SpringBoot的Context和Jersey的Context是不同的。要修复这个问题可以基于SpringBoot的Context来构建测试时Jersey的Context,但是这样做也会遇到一些问题。具体什么问题懒得说了。直接说解决方案:跳过Jersey的Context,不使用JerseyTest抽象类,直接自行创建WebTarget实例。
看一个测试超类代码示例好了:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = MyApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class JerseyTestBase {
private static Logger logger = LoggerFactory.getLogger(JerseyTestBase.class);
@Value("${local.server.port}")
private int port;
public Response get(String path) {
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:" + port + "/api" + path);
return target.request(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).get();
}
}
就这样。
#############