2017-09-04 80 views
3

爲使用RestTemplate(和引擎蓋下的功能區)和Eureka解決服務B的Spring Boot應用程序(服務A)編寫集成測試依賴關係,當調用服務A時,我得到「無實例可用」異常。使用WireMock和Eureka進行Spring Boot集成測試失敗,出現「沒有可用實例」

我嘗試通過WireMock模擬服務B,但我甚至都沒有使用WireMock服務器。似乎RestTemplate試圖從Eureka中獲取服務實例,該實例在我的測試中沒有運行。它通過屬性被禁用。

服務A呼叫服務B. 通過RestTemplate,Ribbon和Eureka完成服務發現。

有沒有人有一個包含Spring,Eureka和WireMock的工作示例?

+0

如果你都還好用嘲諷的服務B,您可以用'MockRestServiceServer'。我可以分享一個例子。 – barbakini

+0

這可能是一個選項,但我想包括實際的服務電話,即使響應是罐裝的。 – derSteve

+0

當使用'MockRestServiceServer'時,spring啓動實際上是一個調用。但只有它被'MockRestServiceServer'所捕獲,並且它返回你確定的響應。對於尤里卡部分。它已經是一個熟練的框架工作,你不需要測試它(對於色帶或負載平衡問題等) – barbakini

回答

0

這是我在我的項目完成:

某處在您的項目配置:

@LoadBalanced 
@Bean 
public RestTemplate restTemplate(RestTemplateBuilder builder) { 
    RestTemplate restTemplate = builder.build(); 
    restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); 
    return restTemplate; 
} 

@Bean 
public SomeRestClass someRestClass() { 
    SomeRestClass someRestClass = new SomeRestClass (environment.getProperty("someservice.uri"), restTemplate(new RestTemplateBuilder())); 
    return parameterRest; 
} 

而且SomeRestClass:

public class SomeRestClass { 

    private final RestTemplate restTemplate; 

    private final String someServiceUri; 

    public LocationRest(String someServiceUri, RestTemplate restTemplate) { 
     this.someServiceUri= someServiceUri; 
     this.restTemplate = restTemplate; 
    } 

    public String getSomeServiceUri() { 
     return locationUri; 
    } 

    public SomeObject getSomeObjectViaRest() { 
     //making rest service call 
    } 
} 

與測試類SomeRestClass

@RunWith(SpringRunner.class) 
@RestClientTest(SomeRestClass.class) 
public class SomeRestClassTest { 
    @Autowired 
    private SomeRestClass someRestClass; 

    @Autowired 
    private MockRestServiceServer server; 

    @Test 
    public void getSomeObjectViaRestTest() throws JsonProcessingException { 
     SomeResponseObject resObject = new SomeResponseObject(); 
     ObjectMapper objectMapper = new ObjectMapper(); 
     String responseString = objectMapper.writeValueAsString(resObject); 

     server.expect(requestTo(locationRest.getSomeServiceUri() + "/some-end-point?someParam=someParam")).andExpect(method(HttpMethod.POST)) 
      .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON_UTF8).body(responseString)); 
     someRestClass.getSomeObjectViaRest(); 

    } 
} 

注意:我爲eureka客戶端進行了diasble,因爲否則您必須嘲笑一個尤里卡服務器。所以我加了測試eureka.client.enabled =假 application.properties中

+0

在這種情況下,RestTemplate是否意識到沒有ServiceRegistry/Eureka請求特定的服務端點?在我的測試中,它沒有意識到這一點,並試圖解決來自尤里卡的服務。這就是我得到例外的原因。我的設置eureka.client.enabled = false設置在我的配置中 - >這意味着它不會將自己註冊爲eureka作爲服務本身。 – derSteve

+0

@derSteve是的,RestTemplate只是嘗試點擊地址,MockRestServiceServer捕獲該請求。已發佈的示例已完成,我將其從我的項目中剪切掉,然後使用eureka和RestTemplate。這個測試可以給你你想要的。離這個測試更遠的一步是通過ruby-cucumber或任何其他QA相關技術編寫** real **集成測試,並在測試環境中運行這些測試,並實際運行服務A,服務B和eureka服務 – barbakini

0

我昨天遇到同樣的問題,爲了完整起見,這裏是我的解決方案:

這是我的「活」的配置下src/main/java/.../config

//the regular configuration not active with test profile 
@Configuration 
@Profile("!test") 
public class WebConfig { 
    @LoadBalanced 
    @Bean 
    RestTemplate restTemplate() { 
     //you can use your regular rest template here. 
     //This one adds a X-TRACE-ID header from the MDC to the call. 
     return TraceableRestTemplate.create(); 
    } 
} 

我加入此配置以測試夾src/main/test/java/.../config

//the test configuration 
@Configuration 
@Profile("test") 
public class WebConfig { 
    @Bean 
    RestTemplate restTemplate() { 
     return TraceableRestTemplate.create(); 
    } 
} 

在測試情況下,我啓用配置文件test

//... 
@ActiveProfiles("test") 
@RunWith(SpringRunner.class) 
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 
public class ServerCallTest { 
    @Autowired 
    private IBusiness biz; 

    @Autowired 
    private RestTemplate restTemplate; 

    private ClientHttpRequestFactory originalClientHttpRequestFactory; 

    @Before 
    public void setUp() { 
     originalClientHttpRequestFactory = restTemplate.getRequestFactory(); 
    } 

    @After 
    public void tearDown() { 
     restTemplate.setRequestFactory(originalClientHttpRequestFactory); 
    } 

    @Test 
    public void fetchAllEntries() throws BookListException { 
     MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate); 

     mockServer     
      .andExpect(method(HttpMethod.GET)) 
      .andExpect(header("Accept", "application/json")) 
      .andExpect(requestTo(endsWith("/list/entries/"))) 
      .andRespond(withSuccess("your-payload-here", MediaType.APPLICATION_JSON)); 

     MyData data = biz.getData(); 

     //do your asserts 
    } 
} 
相關問題