外部web siteのresponseのtestにWireMock を使ったのでメモ。
参考: WireMockを使って通信に関するテストをやってみよう
使う時はbuild.gradleで、
1
testCompile 'com.github.tomakehurst:wiremock-standalone:2.15.0'
して(wiremock-standaloneでないと、 jetty系のClassNotFoundExceptionに見舞われた)から、 test classの方で、
1
2
3
4
5
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
:
@Rule
public WireMockRule wireMockRule = new WireMockRule(8089);
とし、各test method内で、
1
2
3
4
5
6
7
stubFor(post(urlPathEqualTo("/any_path"))
.withRequestBody(matching(".*arr_stn=%96%BC%8C%C3%89%AE.*"))
.withRequestBody(matching(".*dep_stn=%93%8C%8B%9E.*"))
.withRequestBody(matching(".*train=1.*"))
.willReturn(aResponse()
.withStatus(200)
.withBodyFile("for_test.html")));
とstatic importした com.github.tomakehurst.wiremock.client.WireMock.stubForを使えば良い。 matching rule詳細は公式ページ を。 post body requestに対して.withQueryParam("...", matching("..."))は効かなかった。 また、matchingなので全体にmatchingさせる必要があることに注意。 find系はなし。
test対象classでのqueryがここでの指定に合わなければ、404がthrowされる。
上記のように、test用に既に用意してあるhtml fileを.withBodyFile("...")で指定でき、 実体はsrc/test/resources/__files/に置く。 .withBodyFile(...)は公式Docに無く、JavaDoc APIも無いので、 Github上のsource code を眺めて見つけた。
こうしたmappingをsrc/test/resources/mappings/以下にanyName.jsonを置いて、 requestとresponseを指定できるのだが、 それだと「こういうrequest bodyの時はこのようなresponse、 こっちの時はこれこれのresponse」というように、 複数の条件を書くことが出来なかった (書いてみると、最後のrequest/response条件しか効かず。 ならばと複数fileに分けてみたら、 file名alphabeticalで最後のrequest/responseしか効かず)。 なので、Javaでstub条件書いて各test method内に書くしか無い?
これはSpringの話だが、 testの時だけlocalhost:8089を見るようにするには、 〜.config.ApplicationProperties classにfield定義、setter/getterのaccessorを付け、src/main/resources/config/application.ymlのapplication:以下に通常時の値を、src/test/resources/config/application.ymlのapplication:以下にtest時の値(この場合はhttp://localhost:8089/any_path)を記述。 実際に使うには、
1
2
@Autowired
private ApplicationProperties properties;
とDIさせて、properties.get〜()と普通にgetterでget。
AssertJ、method chainで書けるので、 static importがassertThatだけで済んでいいですね。
これはJHipsterの話?(Springかなぁ?)で、 Test Class内で@Autowiredしてるservice classのmockが必要になったら、 特にbuild.gradeに記述せずともimport org.mockito.Mock;して mockitoの@Mockが使えるんですね。 そう言えば、元々import org.mockito.MockitoAnnotations;されてますね。