如http://spockframework.org/spock/docs/1.3/interaction_based_testing.html#_explicit_interaction_blocks中所述,我在then:
块中使用interaction{}
,如下所示:
Java代码:
// legacy code (still running on EJB 1.0 framework, and no dependency injection involved)
// can't alter java code base
public voidGetData() {
DataService ds = new DataService();
ds = ds.findByOffset(5);
Long len = ds.getOffset() // happy path scenario; missing a null check
// other code
}
// other varieties of same code:
public voidGetData2() {
ItemEJB tmpItem = new ItemEJB();
ItemEJB item = tmpItem.findByOffset(5);
if(null != item) {
Long len = item.getOffset();
// other code
}
}
public voidGetData3() {
ItemEJB item = new ItemEJB().findByOffset(5);
if(null != item) {
Long len = item.getOffset();
// other code
}
}
斯波克试验:
def "test scene1"() {
given: "a task"
// other code ommitted
DataService mockObj = Mock(DataService)
when: "take action"
// code omitted
then: "action response"
interaction {
verifyNoDataScenario() // How to add verifyErrorScenario() interaction to the list?
}
}
private verifyDataScenario() {
1 * mockObj.findByOffset(5) >> mockObj // the findByOffset() returns an object, so mapped to same mock instance
1 * mockObj.getOffset() >> 200
}
private verifyErrorScenario() {
1 * mockObj.findByOffset(5) >> null // the findByOffset() returns null
0 * mockObj.getOffset() >> 200 // this won't be executed, and should ie expected to throw NPE
}
你的应用程序代码看起来很奇怪。您的遗留应用程序中的编程风格真的那么糟糕吗?首先,使用无参数构造函数创建DataService
对象,在下一步中通过调用该实例上的方法来覆盖该对象,该方法再次返回DataService
对象。什么样的程序员会创建那样的代码?或者您只是编造了一些与实际应用程序没有太多共同之处的伪代码?请解释一下。
至于您的测试代码,它也没有意义,因为您将DataService Mockobj
实例化为特性方法(测试方法)中的局部变量,这意味着在帮助器方法中Mockobj
无法访问。因此,要么需要将对象作为参数传递给帮助器方法,要么需要将其作为测试类中的字段。
最后,但并非最不重要的一点是,您的本地模拟对象永远不会注入到被测试的类中,因为正如我在第一段中所说,getdata()
中的dataservice
对象也是一个局部变量。除非您的应用程序代码是完全伪造的,否则无法插入模拟,因为getData()
没有任何方法参数,并且DataService
对象不是可以通过setter方法或构造函数设置的字段。因此,您可以根据需要创建任意多个模拟,但应用程序永远不会知道它们。因此,您的stubbingfindbyoffset(长偏移量)
(为什么不显示该方法的代码呢?)没有任何影响。
底线:请提供一个反映实际代码结构的例子,包括应用程序和测试代码。不幸的是,您提供的代码片段没有任何意义。我想帮忙,但就像这样,我做不到。
更新:
在我的注释中,我提到通过添加构造函数、setter方法或带有附加参数的重载getdata
方法来重构遗留代码的可测试性。下面是我的意思的一个例子:
虚拟帮助程序类:
package de.scrum_master.stackoverflow.q58470315;
public class DataService {
private long offset;
public DataService(long offset) {
this.offset = offset;
}
public DataService() {}
public DataService findByOffset(long offset) {
return new DataService(offset);
}
public long getOffset() {
return offset;
}
@Override
public String toString() {
return "DataService{" +
"offset=" + offset +
'}';
}
}
package de.scrum_master.stackoverflow.q58470315;
public class ToBeTestedWithInteractions {
private DataService ds;
public void setDataService(DataService ds) {
this.ds = ds;
}
// legacy code; can't alter
public void getData() {
if (ds == null)
ds = new DataService();
ds = ds.findByOffset(5);
Long len = ds.getOffset();
}
}
package de.scrum_master.stackoverflow.q58470315
import spock.lang.Specification
class RepeatedInteractionsTest extends Specification {
def "test scene1"() {
given: "subject under test with injected mock"
ToBeTestedWithInteractions subjectUnderTest = new ToBeTestedWithInteractions()
DataService dataService = Mock()
subjectUnderTest.dataService = dataService
when: "getting data"
subjectUnderTest.getData()
then: "no error, normal return values"
noExceptionThrown()
1 * dataService.findByOffset(5) >> dataService
1 * dataService.getOffset() >> 200
when: "getting data"
subjectUnderTest.getData()
then: "NPE, only first method called"
thrown NullPointerException
1 * dataService.findByOffset(5) >> null
0 * dataService.getOffset()
}
}
我在spock和groovy的初始阶段,我试图测试一个简单的Spring启动应用程序,并获得 下面是我的java和groovy代码以及异常详细信息 TestController.java TestControllerSpec。棒极了 我确信我的代码遗漏了什么
我有一个关于SPOCK+Drools测试的问题。事情是这样的, 我正在部署的webapp W/O中运行测试(如果这有任何意义的话:))。我将jar添加到类路径中(而不是WEB-INF/libs),现在运行良好。
我想探听Spring Bean的方法调用。我检查了Docs-Spock只能通过构造函数创建间谍。Spock可以用间谍包裹已经存在的物体吗?
我在spock框架测试方面是非常新的,我没有找到任何可以找到所需信息的例子。因此,我认为最好的方法是向一个例子展示我需要拥有的东西。 > 例如。斯波克的测试类: 将数据作为域类: 现在我有了测试,并且想模拟唯一的方法。这意味着每次调用时,都需要有msg成功的对象数据,但是方法中的所有其他方法都应该正常调用。 很可以理解吗?问题是如何将服务类注入/模拟到spock测试类中?
我正在尝试以下场景: 正在申请中。属性设置为max.poll。记录是50 正在申请中。属性设置enable auto commit=false,并将确认模式设置为手动 在我的方法中添加了@KafkaListener,但不提交任何消息,只需阅读、记录,但不进行确认 事实上,在我的Kafka主题中,我有500条消息要消费,所以我期待以下行为: Spring Kafka民意测验()50条消息(偏移0到5
是否有人使用RecyclerView找到了将onClickListener设置为RecyclerView中的项的方法? 请帮帮我...我是初学者:)