我在这件事上纠结了一段时间。是否可以模拟新URL(URL)。openStream()返回一个文件。广州?我正在使用斯波克来尝试这样做。
public class DownloadFile {
public BufferedReader downloadGzipCsvFile(String url) throws MalformedURLException {
BufferedReader br = null;
if (UrlValidator.getInstance().isValid(url)){
try {
br = new BufferedReader(new InputStreamReader(new GZIPInputStream(new URL(url).openStream())));
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
} else{
throw new MalformedURLException("Supplied URL: " + url + " is an invalid URL");
}
return br;
}
}
测试类
class DownloadFileSpec extends Specification{
def "Should return buffered reader for url for gzip csv file"(){
given:
String url = "http://www.test.com"
DownloadFile downloadFile = new DownloadFile()
when:
BufferedReader br = downloadFile.downloadGzipCsvFile(url)
_.openStream() << new FileInputStream("../../../../resources/test_data.csv.gz")
then:
br.ready()
}
}
或者我最好编写一个私有方法来返回流?
可测试性的问题几乎总是一样的:没有依赖注入。这种情况也不例外。这里的具体问题是,您不能简单地提供file://...
URL,因为您使用Apache Commons Validate,这会为isValid(URL)
生成false
。
解决方案是使您的类能够通过setter或其他构造函数注入UrlValidator
。我在示例代码中选择setter方法。如果您不喜欢公共setter,我甚至使setter包范围化,所以您可以将您的测试放入与原始类相同的包中(无论如何这是常见的做法),以便访问它。
现在只需在测试期间注入一个mock并愉快地使用一个文件URL:
package de.scrum_master.stackoverflow;
import org.apache.commons.validator.routines.UrlValidator;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.zip.GZIPInputStream;
public class DownloadFile {
private UrlValidator urlValidator = UrlValidator.getInstance();
void setUrlValidator(UrlValidator urlValidator) {
this.urlValidator = urlValidator;
}
public BufferedReader downloadGzipCsvFile(String url) throws MalformedURLException {
BufferedReader br = null;
if (urlValidator.isValid(url)) {
try {
br = new BufferedReader(
new InputStreamReader(
new GZIPInputStream(
new URL(url).openStream()
)
)
);
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
}
else {
throw new MalformedURLException("Supplied URL: " + url + " is an invalid URL");
}
return br;
}
}
package de.scrum_master.stackoverflow
import org.apache.commons.validator.routines.UrlValidator
import spock.lang.Specification
class DownloadFileSpec extends Specification {
def "Should return buffered reader for url for gzip csv file"() {
given:
String url = new File("src/test/resources/test_data.csv.gz").toURI().toURL()
def downloadFile = new DownloadFile()
downloadFile.urlValidator = Mock(UrlValidator) {
isValid(_) >> true
}
when:
def bufferedReader = downloadFile.downloadGzipCsvFile(url)
then:
bufferedReader.ready()
}
}
顺便说一句,该测试还显示了如何将从相对路径创建的文件
实例转换为文件URL。
注意:您还可以使用PowerMock来模拟静态方法或构造函数,这也可以解决问题。但我相信,无论何时您需要PowerMock,它都是一种代码味道,您应该重构,这就是我为您所做的。
给定一个类Foo 为什么我用Spock来嘲笑Foo 调用总是返回false? 不确定这是否有区别,但测试是在Groovy/Spock中进行的,而Foo是在Java8中进行的。
所以我想做一些事情 但我得到了空异常
我在spring boot应用程序中用groovy(spock)编写了一个集成测试。其中一个应用程序bean称为,它具有以下方法: 在类中还有其他方法。在我的集成测试中,我只想模拟该特定方法的响应。以以下方式: 我希望进行其他验证,但不是这次。基本上,我想实现这一点,但与斯波克。我想取消执行方法
我试图为一个类编写一个单元测试,这个类使用带有库中的的Google vision API。问题是,由于某种原因,我的模拟仍然调用真正的方法,然后抛出一个NPE,这破坏了我的测试。我以前从未在模拟上见过这种行为,我想知道我是不是做错了什么,是不是Spock/Groovy中有bug,还是与Google lib有关?
如何模拟返回已强制转换的模拟对象的方法。 试验方法。
我试图模仿下面的行,但它在执行时给出了一个错误,它说: 此处检测到错误的参数匹配器: when(mock.get(anyInt())).thenreturn(null); doThrow(new RuntimeException()).When(mock).SomeVoidMethod(anyObject()); verify(mock).somemethod(contains(“foo”)) 这