我对Spock Mock()对象有一个问题。我有一个java类正在尝试测试。这个类做了一些我想模拟的ftp内容。我的示例代码
class ReceiveDataTest extends Specification{
String downloadPath = 'downloadPath';
String downloadRegex = 'downloadRegex';
SftpUtils sftpUtils = Mock();
ReceiveData receiveData;
def setup(){
sftpUtils.getFileNames(downloadPath,downloadRegex) >> ['file1', 'file2']
receiveData= new ReceiveData()
receiveData.setDownloadPath(downloadPath)
receiveData.setDownloadRegex(downloadRegex)
receiveData.setSftpUtils(sftpUtils);
}
def "test execute"() {
given:
def files = sftpUtils.getFileNames(downloadPath,downloadRegex)
files.each{println it}
when:
receiveData.execute();
then:
1*sftpUtils.getFileNames(downloadPath,downloadRegex)
}
}
public class ReceiveData(){
//fields, setters etc
public void execute() {
List<String> fileNames = sftpUtils.getFileNames(downloadPath, downloadRegex);
for (String name : fileNames) {
//dowload and process logic
}
}
}
现在,在“test execute”中的文件。each{}打印预期的内容。但当调用receivedata.execute()时,我的sftpUtils返回null。知道为什么吗?
Mockito.when(sftpUtils.getFilenames(downloadPath, downloadRegex)).thenReturn(filenamesList);
receiveData.execute();
Mockito.verify(sftpUtils).getFilenames(downloadPath, downloadRegex);
//this is what I want to test and resides inside for loop
Mockito.verify(sftpUtils).download(downloadPath, filenamesList.get(0));
Mockito.verify(sftpUtils).delete(downloadPath, filenamesList.get(0));
主要的问题是您没有将响应生成器(>>部分)包含在期望中(即then:块中的“1*...”部分)。
这在spock文档中有很好的解释。
>
http://spockframework.org/spock/docs/1.0/interaction_based_testing.html#_combining_mocking_and_stubing
您不必在setup:块中声明存根。您只需要在then:块中指定它一次--即使这是在调用receivedata.execute()之后。由于Groovy AST转换,这就是spock的部分魔力。而且由于(非共享的)字段在每次测试之前都被重新初始化(更多的是基于AST的魔术),在这种情况下甚至不需要setup()。
另一件奇怪的事情是,您既删除了sftputils.getFileNames(),又从测试代码中调用了它。模拟和存根用于替换从测试中的系统调用的协作器。没有理由调用测试驱动程序的存根。因此,从给定块中删除对getFilenames()的调用,并让测试中的代码调用它(正如它所做的那样)。
Groovy允许您简化对Java set和get方法的调用。看看下面receiveData的初始化。在Groovy中使用def是可以的。让编译器为您计算出数据类型。
导致类似于:
class ReceiveDataTest extends Specification {
// only use static for constants with spock
static String PATH = 'downloadPath'
static String REGEX = 'downloadRegex'
def mockSftpUtils = Mock(SftpUtils)
def receiveData = new ReceiveData(downloadPath : PATH,
downloadRegex : REGEX,
sftpUtils : mockSftpUtils)
def "execute() calls getFileNames() exactly once"() {
when:
receiveData.execute()
then:
1 * mockSftpUtils.getFileNames(PATH, REGEX) >> ['file1', 'file2']
0 * mockSftpUtils.getFileNames(_,_)
// The second line asserts that getFileNames() is never called
// with any arguments other than PATH and REGEX, aka strict mocking
// Order matters! If you swap the lines, the more specific rule would never match
}
}
当我测试模拟外部调用时,我没有看到报告的模拟值,而是,并且我的测试失败。我可以在测试类中看到模拟值(报告),但在类中看不到,并且应用程序(方法返回)没有像我预期的那样被修改。 我的期望是:当我在Impl类中模拟外部调用时,模拟值应该在那里可用,其余的一切都会发生,就好像调用了真正的方法来完成单元测试一样。 实现代码: 测试代码:
我试图测试一个简单POST Rest调用,但存在NullPointerException。 我的RestController: 我的单元测试: 由于以下错误,此测试失败:NullPointerException,确切地说,response ResponseEntity对象为Null。 verify输出将执行以下操作: 知道为什么响应是空的吗?我为测试使用了正确的注释,因此应该注入模拟。也许我在这里
我创建了一个接口,以便可以在对话和片段之间进行通信。 目标:当用户从对话框中选择任何内容时,应将其显示在文本视图中。 在这个界面中,我创建了一个界面方法,在主活动中调用,并传递用户在对话框中选择的值。与用户选择的值一起,在我的片段中,我创建了一个方法,将文本视图设置为该值。然而,每当我调用该方法时,它总是返回null。 我对日志进行了大量测试,发现通过我的方法传递的值不是空的,一切似乎都按照我想要
我在这件事上纠结了一段时间。是否可以模拟新URL(URL)。openStream()返回一个文件。广州?我正在使用斯波克来尝试这样做。 测试类 或者我最好编写一个私有方法来返回流?
给定一个类Foo 为什么我用Spock来嘲笑Foo 调用总是返回false? 不确定这是否有区别,但测试是在Groovy/Spock中进行的,而Foo是在Java8中进行的。
我试图模拟一些方法调用,但不幸的是我一直返回null。你能帮我指出我可能出错的地方吗?我正在使用time(). thenBack(),我觉得我正确地模拟了返回变量。事先非常感谢。我是JUnit和Mockito的新手,所以如果我错过了任何明显的东西,我很抱歉。 ServiceTest.java Service.java