簡體   English   中英

與Spock嘲笑的Spring Rest模板

[英]Spring Rest Template mocking with Spock

誰能給我一個例子,如何使用Spock測試RestTemplate。 我的課程看起來像這樣:

@Service
public class SomeService {

    @Autowired
    private EndpointUrlProvider endpointUrlProvider;
    private RestTemplate restTemplate = new RestTemplate();

    public SomeResponse doSomePostRequest(HttpEntity<?> httpEntity) throws Exception {
    ResponseEntity<SomeResponse> response;
            try{
                response = restTemplate.postForEntity(endpointUrlProvider.getSomeUrl(),httpEntity,SomeResponse.class);
            } catch (Exception e){
                throw new Exception("Exception occured during post for:" + httpEntity.getBody().getClass().getSimpleName() + " Cause: " + e.getMessage());
            }
            if(response.getStatusCode() == HttpStatus.OK){
                return response.getBody();
            }
            throw new Exception("Error during " + response.getBody().getClass().getSimpleName() + "Http status is diffrent than 200: " + response.getBody().toString());
        }
    }

測試:

class SomeTest extends Specification {

    RestTemplate restTemplate = Mock {
        postForEntity(_, _, SomeResponse.class) >> new ResponseEntity(new SomeResponse(), HttpStatus.OK)
    }

    @Autowired
    SomeService someService

    def "someTest"() {
        when:
        SomeResponse someResponse = someService.doSomePostRequest(new HttpEntity<>(new SomeBody(), new HttpHeaders()))
        then:
        someResponse == new SomeResponse()
    }
}

主要問題是RestTemplate的模擬行為,我正在尋找解決方案以正確的方式進行。 我不使用彈簧靴。

情況如下:

您在服務類中創建新的RestTemplate

  private RestTemplate restTemplate = new RestTemplate();

然后在測試中創建模擬並調用您的服務方法:

    RestTemplate restTemplate = Mock {
            postForEntity(_, _, SomeResponse.class) >> new ResponseEntity(new SomeResponse(), HttpStatus.OK)
        }
                  ....
    someService.doSomePostRequest

但是您的服務中仍然包含常規的rest模板。 您應該注入模擬對象。 我建議您通過構造函數來實現。 因此,將您的代碼更改為:

@Service
public class SomeService {

private EndpointUrlProvider endpointUrlProvider;
private RestTemplate restTemplate;

@Autowired
public SomeService(EndpointUrlProvider endpointUrlProvider, RestTemplate restTemplate){
  this.endpointUrlProvider = endpointUrlProvider;
  this.restTemplate = restTemplate;
}

您的測試將是:

class SomeTest extends Specification {

    RestTemplate restTemplate = Mock {
        postForEntity(_, _, SomeResponse.class) >> new ResponseEntity(new SomeResponse(), HttpStatus.OK)
    }

    SomeService someService = new SomeService (  null, restTemplate);

    def "someTest"() {
        when:
        SomeResponse someResponse = someService.doSomePostRequest(new HttpEntity<>(new SomeBody(), new HttpHeaders()))
        then:
        someResponse == new SomeResponse()
    }
}

現在您的服務對象將在注入的MOCK上調用方法,而不是通常的RestTemplate

PS

在春季之前,構造函數注入被認為是一種好習慣。

與在所有服務中創建新對象相比,最好創建一個RestTemplate bean並將其注入到各處。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM