Last active
October 31, 2021 14:40
-
-
Save orekyuu/cb0a23b38327a19b8a48dc2a5b4e7964 to your computer and use it in GitHub Desktop.
Nestedを使ったControllerのテスト
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.orekyuu.controllertestdemo; | |
import org.junit.jupiter.api.Nested; | |
import org.junit.jupiter.api.Test; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; | |
import org.springframework.boot.test.context.SpringBootTest; | |
import org.springframework.test.web.servlet.MockMvc; | |
import org.springframework.test.web.servlet.MvcResult; | |
import org.springframework.test.web.servlet.ResultMatcher; | |
import org.springframework.test.web.servlet.result.MockMvcResultMatchers; | |
import org.springframework.test.web.servlet.result.StatusResultMatchers; | |
import static org.assertj.core.api.AssertionsForClassTypes.assertThat; | |
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; | |
// SpringBootのMockMvcのテスト | |
// 辛みとしては、mockMvcの呼び出しが複雑だったりすると同じようなコードをテストケースごとに何度も書かないといけないのでノイジー | |
// 与えるパラメータが違う場合、レスポンスが変わるテストをしたいのでそこだけ抜き出して観点を目立つようにしたい | |
public class SumControllerTest { | |
@SpringBootTest | |
@AutoConfigureMockMvc | |
static abstract class SumControllerTestBase implements TestContext<MvcResult> { | |
@Autowired | |
MockMvc mockMvc; | |
@Override | |
public MvcResult subject() throws Exception { | |
return mockMvc.perform(post("/sum").param("a", String.valueOf(paramA())).param("b", String.valueOf(paramB()))) | |
.andExpect(status(MockMvcResultMatchers.status())) | |
.andReturn(); | |
} | |
abstract ResultMatcher status(StatusResultMatchers s); | |
public String paramA() { | |
return "1"; | |
} | |
public String paramB() { | |
return "2"; | |
} | |
@Override | |
public void it(MvcResult result) throws Exception { | |
} | |
} | |
@Nested | |
class Succeeded extends SumControllerTestBase { | |
@Override | |
ResultMatcher status(StatusResultMatchers s) { | |
return s.isOk(); | |
} | |
@Override | |
public void it(MvcResult result) throws Exception { | |
assertThat(result.getResponse().getContentAsString()).isEqualTo("3"); | |
} | |
} | |
@Nested | |
class MinusSucceeded extends SumControllerTestBase { | |
@Override | |
ResultMatcher status(StatusResultMatchers s) { | |
return s.isOk(); | |
} | |
@Override | |
public String paramA() { | |
return "5"; | |
} | |
@Override | |
public String paramB() { | |
return "-10"; | |
} | |
@Override | |
public void it(MvcResult result) throws Exception { | |
assertThat(result.getResponse().getContentAsString()).isEqualTo("-5"); | |
} | |
} | |
@Nested | |
class BadRequestIfStringParam extends SumControllerTestBase { | |
@Override | |
ResultMatcher status(StatusResultMatchers s) { | |
return s.isBadRequest(); | |
} | |
@Override | |
public String paramA() { | |
return "text"; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.orekyuu.controllertestdemo; | |
import org.junit.jupiter.api.Test; | |
// Testのベース | |
public interface TestContext<R> { | |
// テスト対象の呼び出し | |
R subject() throws Exception; | |
// 結果のassertをする場所 | |
void it(R result) throws Exception; | |
// テストの実行 | |
@Test | |
default void doTest() throws Exception { | |
R subject = subject(); | |
it(subject); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.orekyuu.controllertestdemo; | |
import org.junit.jupiter.api.Nested; | |
import java.util.List; | |
import static org.assertj.core.api.Assertions.assertThat; | |
// UserRepositoryなどの単純なクラスのテスト | |
// 辛みとしては、与えるパラメータの組み立てが大変な場合組み立て部分が冗長になってノイジー | |
// 組み立て部分の差分と、テストの観点を目立たせたい | |
class UserRepositoryTest { | |
static abstract class FindAdultUserTestBase implements TestContext<List<User>> { | |
// テスト時する前にDBに入れておきたいUserのList | |
List<User> users() { | |
return List.of(); | |
} | |
// クエリを発行した結果とれる件数 | |
public int resultSize() { | |
return 0; | |
} | |
@Override | |
public List<User> subject() throws Exception { | |
UserRepository repository = new UserRepository(); | |
// setup | |
users().forEach(repository::insert); | |
return repository.findAdultUser(); // 今回のテスト対象は成人したユーザーを見つけてくるメソッド | |
} | |
@Override | |
public void it(List<User> result) throws Exception { | |
// findAdultUserを呼び出した結果、resultSizeと一致するかをテストしたい | |
assertThat(result).hasSize(resultSize()); | |
} | |
} | |
@Nested | |
class IfEmpty extends FindAdultUserTestBase { | |
@Override | |
List<User> users() { | |
return List.of(); | |
} | |
@Override | |
public int resultSize() { | |
return 0; | |
} | |
} | |
@Nested | |
class OnlyNonAdult extends FindAdultUserTestBase { | |
@Override | |
List<User> users() { | |
return List.of(new User(1, 10)); | |
} | |
@Override | |
public int resultSize() { | |
return 0; | |
} | |
} | |
@Nested | |
class OnlyAdult extends FindAdultUserTestBase { | |
@Override | |
List<User> users() { | |
return List.of(new User(1, 22)); | |
} | |
@Override | |
public int resultSize() { | |
return 1; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment