読者です 読者をやめる 読者になる 読者になる

かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

IntelliJ IDEA の起動、簡単な Spring Boot Project の作成&実行 ( その3 )

概要

IntelliJ IDEA の起動、簡単な Spring Boot Project の作成&実行 ( その2 ) の続きです。

  • この手順で確認できるのは以下の内容です。
    • Test の作成、実行

ソフトウェア一覧

参考にしたサイト

  1. spring-boot/spring-boot-samples/spring-boot-sample-jpa のテストクラス
    https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-jpa/src/test/java/sample/jpa/SampleJpaApplicationTests.java

  2. Spring MVC 3.2のSpring MVC Testを触った http://kuwalab.hatenablog.jp/entry/20130402/p1

  3. Spring Framework Reference Documentation の「11.3.6. Spring MVC Test Framework」
    http://docs.spring.io/spring/docs/current/spring-framework-reference/html/testing.html#spring-mvc-test-framework

  4. org.springframework.test.web.servlet.result の Class MockMvcResultMatchers http://docs.spring.io/spring/docs/3.2.0.RELEASE/javadoc-api/org/springframework/test/web/servlet/result/MockMvcResultMatchers.html

手順

test ディレクトリの下に src ディレクトリと同じ package を作成する

  1. Project View で以下の階層にある java ディレクトリの下に src/main/java の下と同じ package を作成します。

     ksbysample-simple
     └ src
        └ test
           └ java

  2. 作成後、ディレクトリ・ファイルは以下の構成になっています。

    f:id:ksby:20141229112741p:plain

TestControllerTest.java の作成、実行

  1. test/java/ksbysample/simple/web の下に TestControllerTest.java を新規作成します。

  2. 作成した TestControllerTest.java をダブルクリックして開き、リンク先のその1の内容に変更します。

  3. Project View で一番上の階層の ksbysample-simple を選択した後コンテキストメニューを表示し、「Run 'Tests in 'ksbysample...' with Coverage」を選択します。

    f:id:ksby:20141229132907p:plain

  4. Run View が表示され Test が実行されます。全ての Test が問題なければ All Tests Passed のメッセージが表示されます。

    f:id:ksby:20141229165020p:plain

  5. Test でエラーが発生した場合の挙動を見てみます。TestControllerTest.java の testIndex method を リンク先のその2の内容に変更します。

  6. Project View から「Run 'Tests in 'ksbysample...' with Coverage」を実行します。

  7. Test でエラーが発生すると以下のように Run View の左側にエラーが発生した Test の class、method が、右側にエラーの内容が表示されます。

    f:id:ksby:20141229170034p:plain

    また Run View の左側に表示されている Click to see difference リンクをクリックすると「Comparison Failure」画面が表示され、より差異が分かりやすく表示されます。

    f:id:ksby:20141229170526p:plain

  8. TestControllerTest.javaリンク先のその1の内容に戻しておきます。

Test2ControllerTest.java の作成、実行

  1. test/java/ksbysample/simple/web の下に Test2ControllerTest.java を新規作成します。

  2. 作成した Test2ControllerTest.java をダブルクリックして開き、リンク先の内容に変更します。

  3. Run View の左側にある Rerun ボタンか Ctrl+F5 を押してテストを再実行し、All Tests Passed のメッセージが表示されることを確認します。

    f:id:ksby:20141229172038p:plain

ApplicationTest.java の作成、実行

  1. test/java/ksbysample/simple の下に ApplicationTest.java を新規作成します。

  2. 作成した ApplicationTest.java をダブルクリックして開き、リンク先の内容に変更します。

  3. Run View の左側にある Rerun ボタンか Ctrl+F5 を押してテストを再実行し、All Tests Passed のメッセージが表示されることを確認します。

  4. 以上で Test は完了です。IntelliJ IDEA の画面左側に Coverage が表示されますが、全て 100% になりました。

    f:id:ksby:20141229175747p:plain

  5. ここまでで Project のディレクトリ・ファイルは以下の構成になっています。

    f:id:ksby:20141229182352p:plain

ソースコード

TestControllerTest.java

■その1

package ksbysample.simple.web;

import ksbysample.simple.Application;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class TestControllerTest {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mvc;

    @Before
    public void setUp() {
        this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
    }

    @Test
    public void testIndex() throws Exception {
        this.mvc.perform(get("/test")).andExpect(status().isOk())
                .andExpect(content().contentType("text/plain;charset=UTF-8"))
                .andExpect(content().string("これは /test のページです。Tomcat起動中に文字列を追加してみました。"));
    }

    @Test
    public void testThymeleafSample() throws Exception {
        this.mvc.perform(get("/test/thymeleaf-sample")).andExpect(status().isOk())
                .andExpect(content().contentType("text/html;charset=UTF-8"))
                .andExpect(view().name("test/thymeleaf-sample"))
                .andExpect(content().string(containsString("これは /test/thymeleaf-sample のページです。")))
                .andExpect(xpath("/html/body/span[1]").string("引数 model を追加してみました。"))
                .andExpect(xpath("/html/body/span[2]").string("田中 太郎"))
                .andExpect(xpath("/html/body/span[3]").string("03-1234-5678"));
    }

    @Test
    public void testAddurl() throws Exception {
        this.mvc.perform(get("/test/addurl")).andExpect(status().isOk())
                .andExpect(content().contentType("text/plain;charset=UTF-8"))
                .andExpect(content().string("これは /test/addurl のページです。"));
    }

}

■その2

    @Test
    public void testIndex() throws Exception {
        this.mvc.perform(get("/test")).andExpect(status().isOk())
                .andExpect(content().contentType("text/html;charset=UTF-8"))
                .andExpect(content().string("これは /test のページです。Tomcat起動中に文字列を追加してみました。"));
    }
  • text/plain;charset=UTF-8text/html;charset=UTF-8 へ変更します。

Test2ControllerTest.java

package ksbysample.simple.web;

import ksbysample.simple.Application;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class Test2ControllerTest {

    @Autowired
    private WebApplicationContext context;

    private MockMvc mvc;

    @Before
    public void setUp() {
        this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
    }

    @Test
    public void testIndex() throws Exception {
        this.mvc.perform(get("/test2")).andExpect(status().isOk())
                .andExpect(content().contentType("text/plain;charset=UTF-8"))
                .andExpect(content().string("これは /test2 のページです。"));
    }

}

ApplicationTest.java

package ksbysample.simple;

import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.test.OutputCapture;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class ApplicationTest {

    @Rule
    public OutputCapture outputCapture = new OutputCapture();

    @Test
    public void testCommandLineOverrides() throws Exception {
        // 標準のPort番号(8080)以外で起動して、"Started Application" のメッセージが出力されるかテストする
        Application.main(new String[] {"--server.port=8081"});
        String output = this.outputCapture.toString();
        assertTrue(output, output.contains("Started Application"));
        // Exceptionが出力されていないかテストする
        assertFalse(output, output.contains("Exception"));
    }

}

履歴

2014/12/29
* 初版発行。

2015/01/03 * ApplicationTest.java 内の不要な import 文を削除しました。