Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
未执行spock测试中的模拟java类_Java_Unit Testing_Mocking_Spock - Fatal编程技术网

未执行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

我试图使用spock框架对一些java类进行单元测试。结构如下所示:

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
    上调用另一个方法,以便将查询结果转换为
    字符串
为什么模拟不起作用? 在解决了这个问题之后,让我们看看你的测试到底有什么根本性的错误

我做错了什么

假设局部变量中的mock在应用程序代码中的其他局部变量中是有效的。为了使用mock,您需要将它注入到被测试的类中。但和许多开发人员一样,您并没有通过依赖项注入来设计解耦和可测试性,而是在内部创建依赖项(在本例中是
DatabaseQuery
对象)

考试还有什么问题吗? 我想你的测试只是规格太高了。为什么要检查另一个类中的特定方法是否从私有方法(间接地)调用?您不直接测试私有方法,而是通过调用公共方法覆盖它们的代码,您的测试已经做到了这一点

如果您想覆盖
catch
块,只需确保您的请求导致了正确的异常。可能需要为此模拟数据库连接,并确保它将预期结果返回到
数据库查询
。我没有看到足够的代码,以便准确地说

原始问题的技术解决方案 现在让我们假设你绝对想要检查这个交互,不管我之前说了什么。您需要做什么取决于具体情况(代码中没有显示):

在任何情况下,都需要使
数据库查询
可注入。您只需向类中添加一个成员和另一个setter即可

现在,根据交互
dbquery.executeQuery(; as String)
的生成(调用)位置,您有了一个岔路口:

  • 如果该方法是从外部调用的,则可以插入一个普通的
    模拟
  • 如果该方法是从
    DatabaseQuery
    内部调用的,则需要插入
    Spy
    ,因为mock不会调用其他内部方法,比如原始对象,因为它只是一个mock
  • 案例1:
    executeQuery(字符串)
    从外部调用

    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(请求