在 Spock 中模拟 RestOperations.exchange(使用可变参数的重载方法)

Mocking RestOperations.exchange in Spock (overloaded method with varargs)

我正在尝试在 Spock 中模拟 org.springframework.web.client.RestOperations.exchange。 Spock 失败

Too few invocations for:

1 * restOperations.exchange("https://test.com", HttpMethod.POST, _ as HttpEntity, String)   (0 invocations)

Unmatched invocations (ordered by similarity):

1 * restOperations.exchange('https://test.com', POST, <whatever,[]>, class java.lang.String, [])

我认为问题与 exchange 方法重载以及我尝试调用的版本具有可变参数有关。

如何定义此交互,以便测试成功?

MySubject.java:


import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.web.client.RestOperations;

public class MySubject {
    private final RestOperations rest;

    public MySubject(RestOperations rest) {
        this.rest = rest;
    }

    public void doStuff() {
        HttpEntity<String> httpEntity = new HttpEntity<>("whatever");
        rest.exchange("https://test.com", HttpMethod.POST, httpEntity);
    }
}

MyTest.groovy:


import org.apache.http.HttpEntity
import org.springframework.http.HttpMethod
import org.springframework.web.client.RestOperations
import spock.lang.Specification

class MyTest extends Specification {
    RestOperations restOperations = Mock(RestOperations)
    MySubject subject = new MySubject(restOperations)

    def "test"() {
        when:
        subject.doStuff()
        then:
        1 * restOperations.exchange("https://test.com", HttpMethod.POST, _ as HttpEntity, String)
    }
}

您有多个问题:

  1. 在您导入的应用程序中org.springframework.http.HttpEntity,在测试中org.apache.http.HttpEntity。你需要更正它。

  2. 您的应用程序中的调用 rest.exchange("https://test.com", HttpMethod.POST, httpEntity); 甚至无法编译,因为 RestOperations class 中没有这样的签名。您需要添加参数 String.class.

  3. 在测试中你需要反映方法签名包括varargs,即真正的方法签名有5个参数。

如果您修复了所有这些问题,您的测试将顺利运行:

package de.scrum_master.Whosebug.q61135628;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.web.client.RestOperations;

public class MySubject {
  private final RestOperations rest;

  public MySubject(RestOperations rest) {
    this.rest = rest;
  }

  public void doStuff() {
    HttpEntity<String> httpEntity = new HttpEntity<>("whatever");
    rest.exchange("https://test.com", HttpMethod.POST, httpEntity, String.class);
  }
}
package de.scrum_master.Whosebug.q61135628

import org.springframework.http.HttpMethod
import org.springframework.web.client.RestOperations
import spock.lang.Specification

class MyTest extends Specification {
  RestOperations restOperations = Mock()
  MySubject subject = new MySubject(restOperations)

  def "test"() {
    when:
    subject.doStuff()

    then:
    1 * restOperations.exchange("https://test.com", HttpMethod.POST, _, String, _)
    // Or if you want to be more specific:
//  1 * restOperations.exchange("https://test.com", HttpMethod.POST, _, String, [])
  }
}