第一个类如下所示:
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)
}
}
我试图为这个RequestProcessor
类编写一个Spock测试,该类依赖于DatabaseQuery
。我正在考虑模拟DatabaseQuery
类,以便单独测试RequestProcessor
类。
正在调用RequestProcessor
的ProcessRequest()
方法,该方法依赖于另一个私有方法。该方法将使用DatabaseQuery
获取实际查询结果。这就是我的Spock测试的样子:
class RequestProcessorSpec extends Specification {
//Class to be tested
RequestProcessor requestProcessor
//Dependencies
DatabaseQuery dbquery
def "Given a valid request, dbquery's executeQuery method is called" () {
given: "a valid request"
def queryRequest = '{"info1":"value1","info2":"value2","query":"select * from users"}'
and: "mock the DBQuery class"
dbquery = Mock(DatabaseQuery)
and: "create a new request"
requestProcessor = new RequestProcessor(queryRequest)
when: "the request is processed"
requestHandler.processRequest()
then: "dbquery executeQuery method is called"
1 * dbquery.executeQuery(_ as String)
}
}
首先,即使我对示例代码进行了简化并创建了自己的虚拟DatabaseQuery
类,示例代码也无法工作,因为这里至少有三个错误:
this.request=request
(自赋值),但应该是this.request=arequest;
.requestHandler.processRequest()
,但应该是requestProcessor.processRequest()
.executeRequest()
不返回指定的字符串
。所以我只能推测,实际上它在DatabaseQuery
上调用了另一个方法,以便将查询结果转换为字符串
.解决了这个问题之后,让我们看看你的测试到底有什么根本问题。
我想你的测试只是规格过高。为什么要检查另一个类中的特定方法是否从私有方法调用(间接调用)?您不直接测试私有方法,而是通过调用公共方法覆盖它们的代码,您的测试已经这样做了。
如果要覆盖catch
块,只需确保请求导致正确的异常。也许您需要为此模拟数据库连接,并确保它将预期的结果返回到DatabaseQuery
。我没有看到足够的代码来准确地说。
现在让我们假设你绝对想检查这个交互,不管我之前说过什么。您需要做什么取决于情况(代码中没有显示):
在任何情况下,都需要使DatabaseQuery
可注入。您只需向类中添加一个成员和另一个setter即可。
现在,根据交互dbquery.executeQuery(_as String)
的来源,您有了一个岔路口:
databasequery
外部调用该方法,则可以插入一个普通的mock
.databasequery
内部调用该方法,则需要注入spy
,因为模拟不会调用其他内部方法,比如原始对象,因为--嗯,它只是一个模拟。package de.scrum_master.query;
public class DatabaseQuery {
private String request;
public DatabaseQuery(String request) {
this.request = request;
}
public String executeQuery(String request) {
return request.toUpperCase();
}
public String getResult() {
return executeQuery(request);
}
}
package de.scrum_master.requests;
import de.scrum_master.query.DatabaseQuery;
public class RequestProcessor {
private String request;
private DatabaseQuery databaseQuery;
public RequestProcessor(String aRequest) {
this.request = aRequest;
databaseQuery = new DatabaseQuery(request);
}
public String processRequest() {
return executeRequest();
}
private String executeRequest() {
return databaseQuery.executeQuery(request);
//return databaseQuery.getResult();
}
public void setDatabaseQuery(DatabaseQuery databaseQuery) {
this.databaseQuery = databaseQuery;
}
}
package de.scrum_master.requests
import de.scrum_master.query.DatabaseQuery
import spock.lang.Specification
class RequestProcessorTest extends Specification {
//Class to be tested
RequestProcessor requestProcessor
//Dependencies
DatabaseQuery dbquery
def "Given a valid request, dbquery's executeQuery method is called" () {
given: "a valid request"
def queryRequest = '{"info1":"value1","info2":"value2","query":"select * from users"}'
and: "mock the DBQuery class"
dbquery = Mock(DatabaseQuery)
//dbquery = Spy(DatabaseQuery, constructorArgs: [queryRequest])
and: "create a new request"
requestProcessor = new RequestProcessor(queryRequest)
requestProcessor.databaseQuery = dbquery
when: "the request is processed"
requestProcessor.processRequest()
then: "dbquery executeQuery method is called"
1 * dbquery.executeQuery(_ as String)
}
}
现在测试工作了,包括交互检查。
情况2:executeQuery(String)
从自己的类内部调用
您看到requestprocessor
和requestprocessortest
中的两行注释掉了吗?只需使用它们,然后像这样注释掉另外两个:
private String executeRequest() {
//return databaseQuery.executeQuery(request);
return databaseQuery.getResult();
}
and: "mock the DBQuery class"
//dbquery = Mock(DatabaseQuery)
dbquery = Spy(DatabaseQuery, constructorArgs: [queryRequest])
我是Spock框架的新手,在使用抽象java测试类时遇到了问题。 我想要的是一个groovy测试类,它用一些常用的方法扩展一些其他java抽象类,这些方法反过来扩展规范类。 当我运行GroovyTest类时,我得到以下错误: Org.SpockFramework.Runtime.InvalidSpecException:规范“org.my.package.AbstractTest”未正确编译(Sp
执行testng xml时,它在套件中只执行1个测试 基本测试- 登录测试-
我试图测试一个使用@inject注入成员的Java类。 我想测试一下 我的类没有显式构造函数
我想现在,如果有可能模仿一个类一样 我们的业务逻辑在代码中的某个地方用< code>new myClass()创建了这个对象,因此我不能访问创建的对象来模拟这些方法。有没有办法替换整个类或者覆盖那些方法。我正在使用mockito,我只找到了这样做的例子 我们不能使用 PowerMock,因为它与我们的测试环境不兼容。 欢迎任何建议。
我正在为扩展了B类的a类编写单元测试。我正在使用Mockito,我想模拟一个组织。slf4j。这两个类都可以使用。问题是,当类A从类B调用方法时,模拟记录器没有被注入到类B中,所以我得到了一个NPE。有没有办法成功地测试这一点?
我这样做是为了得到想要的结果