質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JUnit

JUnitは、Javaで開発されたプログラムのユニットテストを行うためのアプリケーションフレームワークです。簡単にプログラムのユニットテストを自動化することができ、結果もわかりやすく表示されるため効率的に開発時間を短縮できます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

解決済

1回答

13030閲覧

RestTemplateを使ったコントローラーのテストでI/O error on POST requestが発生する

退会済みユーザー

退会済みユーザー

総合スコア0

JUnit

JUnitは、Javaで開発されたプログラムのユニットテストを行うためのアプリケーションフレームワークです。簡単にプログラムのユニットテストを自動化することができ、結果もわかりやすく表示されるため効率的に開発時間を短縮できます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

0グッド

0クリップ

投稿2019/05/04 15:37

編集2019/05/05 16:54

Spring Bootのコントローラー内でRestTemplateを使った外部HTTPアクセスを実装しています。
JUnitで正常系のテストを実行したのですが、RestClientExceptionが発生し、メソッドの最後まで到達ができません。
デバックしてみると、下記のようなエラーメッセージがでてきたのですが、解決方法がよくわかりません。
どのように対処すればよいのでしょうか。

I/O error on POST request for "外部URL": Connection refused: connect

SampleControllerTest

1@RunWith(SpringRunner.class) 2@SpringBootTest 3public class SampleControllerTest { 4 private MockMvc mockMvc; 5 6 @InjectMocks 7 private SampleController controller; 8 9 @Before 10 public void setUp() throws Exception { 11 MockitoAnnotations.initMocks(this); 12 mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); 13 } 14 15 @Test 16 public void sample() throws Exception { 17 Map<String, String> map = new LinkedHashMap<String, String>(); 18 19 MockRestServiceServer mockServer = MockRestServiceServer.createServer(new RestTemplate()); 20 mockServer 21 .expect(requestTo("外部URL")) 22 .andExpect(method(HttpMethod.POST)) 23 .andRespond(withSuccess(map.toString(), MediaType.APPLICATION_JSON_UTF8)); 24 25 mockMvc.perform(post("/")) 26 .andExpect(status().isOk()) 27 .andExpect(view().name("index")); 28 } 29 30} 31

SampleController

1@Controller 2public class SampleController { 3 @RequestMapping(value = "/", method = RequestMethod.POST) 4 public ModelAndView index() { 5 ModelAndView modelAndView = new ModelAndView(); 6 7 MultiValueMap<String, String> formParams = new LinkedMultiValueMap<>(); 8 formParams.add("data", "data"); 9 10 HttpHeaders httpHeaders = new HttpHeaders(); 11 httpHeaders.add(HttpHeaders.AUTHORIZATION, "Basic XXXXXXXXXX"); 12 httpHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE); 13 RequestEntity<MultiValueMap<String, String>> requestEntity = new RequestEntity<>(formParams, httpHeaders, 14 HttpMethod.POST, URI.create("外部URL")); 15 16 RestTemplate restTemplate = new RestTemplate(); 17 18 ResponseEntity<Map<String, String>> responseEntity = null; 19 try { 20 responseEntity = restTemplate.exchange(requestEntity, new ParameterizedTypeReference<Map<String, String>>() {}); 21 } catch (RestClientException e) { 22 modelAndView.setViewName("error"); 23 return modelAndView; 24 } 25 26 modelAndView.setViewName("index"); 27 return modelAndView; 28 } 29}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/05/06 23:03

モックサーバーに向けてるからでは? 外部サーバーのテストは不要かと
退会済みユーザー

退会済みユーザー

2019/05/12 18:13

テストクラスでパラメータを設定した内容がresponseEntityで取得できることを想定したのですが、 モックサーバーを使わずに、対象のサーバーを立ち上げてのテストのほうがよろしいのでしょうか。
guest

回答1

0

ベストアンサー

SampleController内で、RestTemplateのインスタンスを new から作り出しているのでSpring管理にならず、そのためテスト実行時にMockServerを指定してもSampleControllerはMockServerを使いません。

例えば、

java

1import org.springframework.web.bind.annotation.GetMapping; 2import org.springframework.web.bind.annotation.RequestMapping; 3import org.springframework.web.bind.annotation.RestController; 4import org.springframework.web.client.RestOperations; 5 6import lombok.Data; 7import lombok.RequiredArgsConstructor; 8 9@RestController 10@RequestMapping("/outbound") 11@RequiredArgsConstructor 12public class OutBoundSampleController { 13 14 private final RestOperations restOperations; 15 16 @GetMapping("") 17 public SampleModel findOne() { 18 return restOperations.getForObject("https://api.domain/sample/{id}", SampleModel.class, 123); 19 } 20 21 @Data 22 public static class SampleModel { 23 private String name; 24 } 25}

このControllerに対し、Mockitoを使ったControllerのテストを書くならば、

java

1import static org.hamcrest.MatcherAssert.*; 2import static org.hamcrest.Matchers.*; 3import static org.springframework.test.web.client.match.MockRestRequestMatchers.*; 4import static org.springframework.test.web.client.response.MockRestResponseCreators.*; 5 6import org.junit.Before; 7import org.junit.Test; 8import org.junit.runner.RunWith; 9import org.mockito.MockitoAnnotations; 10import org.springframework.beans.factory.annotation.Autowired; 11import org.springframework.boot.test.context.SpringBootTest; 12import org.springframework.http.HttpMethod; 13import org.springframework.http.MediaType; 14import org.springframework.test.context.junit4.SpringRunner; 15import org.springframework.test.web.client.MockRestServiceServer; 16import org.springframework.test.web.servlet.MockMvc; 17import org.springframework.test.web.servlet.setup.MockMvcBuilders; 18import org.springframework.web.client.RestTemplate; 19 20import com.fasterxml.jackson.core.JsonProcessingException; 21import com.fasterxml.jackson.databind.ObjectMapper; 22import com.github.apz.springsample.controller.OutBoundSampleController; 23import com.github.apz.springsample.controller.OutBoundSampleController.SampleModel; 24 25@RunWith(SpringRunner.class) 26@SpringBootTest 27public class OutBoundSampleControllerTest { 28 29 @Autowired 30 private RestTemplate restTemplate; 31 32 33 private MockMvc mockMvc; 34 35 @Autowired 36 private OutBoundSampleController controller; 37 38 @Before 39 public void setUp() throws Exception { 40 MockitoAnnotations.initMocks(this); 41 mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); 42 } 43 44 @Test 45 public void モックサーバテスト() { 46 47 SampleModel testResult = new SampleModel(); 48 ObjectMapper mapper = new ObjectMapper(); 49 String result = null; 50 try { 51 result = mapper.writeValueAsString(testResult); 52 } catch (JsonProcessingException e) { 53 e.printStackTrace(); 54 } 55 56 MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate); 57 mockServer.expect(requestTo("https://api.domain/sample/123")) 58 .andExpect(method(HttpMethod.GET)) 59 .andRespond(withSuccess(result, MediaType.APPLICATION_JSON)); 60 61 SampleModel response = controller.findOne(); 62 63 assertThat(response, is(testResult)); 64 65 mockServer.verify(); 66 67 } 68} 69

実際にController内部からリクエストされるであろうURLの情報を設定するところと、MockServerの設定方法の考え方はあっていますので、RestTemplateの扱い方ですね。

投稿2019/05/13 16:14

A-pZ

総合スコア12011

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/06/02 17:49

ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問