未执行spock测试中的模拟java类
我试图使用spock框架对一些java类进行单元测试。结构如下所示:未执行spock测试中的模拟java类,java,unit-testing,mocking,spock,Java,Unit Testing,Mocking,Spock,我试图使用spock框架对一些java类进行单元测试。结构如下所示: public class RequestProcessor { private String request; public RequestProcessor(String aRequest) { this.request = request; } public String processRequest() { String response ; //do
public class RequestProcessor {
private String request;
public RequestProcessor(String aRequest) {
this.request = request;
}
public String processRequest() {
String response ;
//do something here
try {
if(condition meets) {
response = executeRequest();
}
} catch ( various exceptions... ) {
System.out.println("something went wrong...");
}
}
private String executeRequest() throws <<exceptions thrown by DatabaseQuery>> {
//do something here
DatabaseQuery queryResult = new DatabaseQuery(request)
}
}
(类名:com.myorg.requests
)RequestProcessor
(类名:com.myorg.query
)DatabaseQuery
public class RequestProcessor {
private String request;
public RequestProcessor(String aRequest) {
this.request = request;
}
public String processRequest() {
String response ;
//do something here
try {
if(condition meets) {
response = executeRequest();
}
} catch ( various exceptions... ) {
System.out.println("something went wrong...");
}
}
private String executeRequest() throws <<exceptions thrown by DatabaseQuery>> {
//do something here
DatabaseQuery queryResult = new DatabaseQuery(request)
}
}
这对我来说不太管用。我得到一个错误:
- 调用太少
- 无与伦比的调用
gradlew test--info
运行测试以获得更多结果时,我看到控制台上打印了一个日志,该日志由processRequest
方法中的try-catch语句捕获
我做错了什么?示例代码中的问题
首先,您的示例代码不起作用,即使我简化了它并创建了自己的虚拟DatabaseQuery
类,因为您在这里至少有三个错误:
- 在构造函数中有
(自赋值),但它应该是this.request=request
this.request=aRequest代码>
- 在测试中,您有
,但应该是requestHandler.processRequest()
requestProcessor.processRequest()
- 方法
不返回指定的executeRequest()
字符串。因此,我只能推测,实际上它在
上调用另一个方法,以便将查询结果转换为DatabaseQuery
字符串
DatabaseQuery
对象)
考试还有什么问题吗?
我想你的测试只是规格太高了。为什么要检查另一个类中的特定方法是否从私有方法(间接地)调用?您不直接测试私有方法,而是通过调用公共方法覆盖它们的代码,您的测试已经做到了这一点
如果您想覆盖catch
块,只需确保您的请求导致了正确的异常。可能需要为此模拟数据库连接,并确保它将预期结果返回到数据库查询
。我没有看到足够的代码,以便准确地说
原始问题的技术解决方案
现在让我们假设你绝对想要检查这个交互,不管我之前说了什么。您需要做什么取决于具体情况(代码中没有显示):
在任何情况下,都需要使数据库查询
可注入。您只需向类中添加一个成员和另一个setter即可
现在,根据交互dbquery.executeQuery(; as String)
的生成(调用)位置,您有了一个岔路口:
模拟
DatabaseQuery
内部调用的,则需要插入Spy
,因为mock不会调用其他内部方法,比如原始对象,因为它只是一个mockexecuteQuery(字符串)
从外部调用
package de.scrum\u master.query;
公共类数据库查询{
私有字符串请求;
公共数据库查询(字符串请求){
this.request=请求;
}
公共字符串执行程序(字符串请求){
返回请求。toUpperCase();
}
公共字符串getResult(){
返回执行(请求);
}
}
package de.scrum\u master.requests;
导入de.scrum\u master.query.DatabaseQuery;
公共类请求处理器{
私有字符串请求;
专用数据库查询数据库查询;
公共请求处理器(字符串请求){
这个。请求=请求;
databaseQuery=新数据库查询(请求);
}
公共字符串processRequest(){
返回executeRequest();
}
私有字符串executeRequest(){
返回databaseQuery.executeQuery(请求);
//返回databaseQuery.getResult();
}
公共void setDatabaseQuery(DatabaseQuery DatabaseQuery){
this.databaseQuery=数据库查询;
}
}
package de.scrum\u master.requests
导入de.scrum\u master.query.DatabaseQuery
导入spock.lang.Specification
类RequestProcessorTest扩展了规范{
//待测类别
请求处理器请求处理器
//依赖关系
数据库查询数据库查询
def“给定一个有效的请求,dbquery的executeQuery方法被调用”(){
给定:“有效请求”
def queryRequest='{“info1”:“value1”,“info2”:“value2”,“query”:“select*from users”}'
和:“模拟DBQuery类”
dbquery=Mock(数据库查询)
//dbquery=Spy(数据库查询,构造函数args:[queryRequest])
和:“创建新请求”
requestProcessor=新的requestProcessor(queryRequest)
requestProcessor.databaseQuery=dbquery
当:“请求已处理”
requestProcessor.processRequest()
然后:“调用dbquery executeQuery方法”
1*dbquery.executeQuery(u为字符串)
}
}
现在测试工作包括交互检查
案例2:executeQuery(String)
是从它自己的类内部调用的
您是否看到了RequestProcessor
和RequestProcessorTest
中注释掉的两行?只需使用它们并注释掉另外两个,如下所示:
public class RequestProcessor {
private String request;
public RequestProcessor(String aRequest) {
this.request = request;
}
public String processRequest() {
String response ;
//do something here
try {
if(condition meets) {
response = executeRequest();
}
} catch ( various exceptions... ) {
System.out.println("something went wrong...");
}
}
private String executeRequest() throws <<exceptions thrown by DatabaseQuery>> {
//do something here
DatabaseQuery queryResult = new DatabaseQuery(request)
}
}
private String executeRequest(){
//返回databaseQuery.executeQuery(请求