如果在java.net.URL
协议的Spring Boot应用程序中使用classpath
,它会按预期工作,因为Spring Boot注册了URLStreamHandlerFactory
。例如new URL("classpath: someFile.whatever")
。
但是当此代码作为JUnit测试执行时,会抛出java.net.MalformedURLException: unknown protocol: classpath
异常。
为JUnit测试初始化Spring上下文时,似乎未注册适当的URLStreamHandlerFactory
。
复制步骤:
1)创建Spring Boot Starter项目(例如,仅使用Starter Web)。
2)在test.json
中添加src/main/resources
文件
3)添加以下bean:
@Component
public class MyComponent {
public MyComponent() throws MalformedURLException {
URL testJson = new URL("classpath: test.json");
System.out.println(testJson);
}
}
4)以Java应用程序启动应用程序正常
5)运行默认的“ contextLoads”测试:
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringUrlTestApplicationTests {
@Test
public void contextLoads() {
}
}
java.net.MalformedURLException: unknown protocol: classpath
引发异常。
在JUnit测试中将URL与类路径资源一起使用的合适方法是什么?
在实际用例中,我无法更改new URL("classpath: test.json")
,因为它来自第3方库。
试图在test.json
中复制src/test/resources
,以测试错误是否可能是由于缺少资源引起的-没有成功。
答案 0 :(得分:6)
最简单快捷的方法是在测试执行之前创建简单的方法,即为“类路径”协议创建和注册处理程序。
@BeforeClass
public static void init() {
org.apache.catalina.webresources.TomcatURLStreamHandlerFactory.getInstance();
}
我刚刚检查了一下,效果很好。这种方法还可以在spring-boot应用程序内部使用
答案 1 :(得分:1)
问题在于,处理协议的类为org.apache.catalina.webresources.TomcatURLStreamHandlerFactory
。您可以使用以下方法修复测试:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MalformedUrlApplicationTests {
@Test
public void contextLoads() {
}
}
但是我认为@borino的答案更好。
答案 2 :(得分:0)
我认为您可以尝试自动连接ResourceLoader,并使用resourceLoader.getResource(“ classpath:/test.json”)加载文件,它将从资源文件夹中加载文件。
答案 3 :(得分:0)
我更喜欢以下使用Apache Commons的方式:
String url = IOUtils.toString(
this.getClass().getResourceAsStream("test.json"),"UTF-8"
);
URL testJson = new URL(url);
文件 test.json =>您可以将其保存在src / test / resources文件夹中->它将从此处加载,使用maven可以为我工作
此处提供了更多类似的方法 How to read a text-file resource into Java unit test?
答案 4 :(得分:0)
Spring没有getData()
可以处理URLStreamHandler
协议的URL。 Spring使用"classpath:"
API处理此协议。加载资源后,您可以获取它的URL。
但是,Java提供了一种支持非标准协议的机制。我找到了一个StackOverflow条目,可以回答您的问题。