・ Spring Framework beginners ・ Junit beginners ・ I want to test the Spring framework controller with Junit! !! !!
・ Spring framework 4.1.6 ・ Junit 4.1.2 ・ Servlet 3.1.0 ・ Hamcrest 2.2 ・ Momo c and 3.3.3.
//Main layer
src.main.java
|
+--- jp.co.demo
+--- controller
+--- dto
+--- form
+--- entity
+--- mapper
+--- service
//Test layer
src.test.java
|
+--- jp.co.demo
| +--- controller
|
src.test.resources
|
+--- META-INF
| |
| +--- sql
| |
| +--- insert_data.sql //SQL for creating test data
|
+--- spring
|
+--- mvc-config.xml //Bean definition file
insert_data.sql
DELETE FROM messages;
DELETE FROM users;
INSERT INTO users(id,account,password,name,branch_id,department_id) VALUES (1,'testuser','$2a$10$i0FlsKe6FiEuViMhclA90uCjCCKeLhtcswz01Rwl9qTIsIY1c.ohO','ALH Taro',1,1);
ALTER TABLE messages MODIFY id int not null; --Temporarily auto-increment reset to auto-increment reset
ALTER TABLE messages AUTO_INCREMENT = 1; --Auto increment reset
ALTER TABLE messages MODIFY id int not null auto_increment; --Auto increment grant
INSERT INTO messages(title,text,category,user_id, created_date)VALUES('title','Text','category',1,'2020-05-27 01:02:03'); --3
INSERT INTO messages(title,text,category,user_id, created_date)VALUES('title','Text','category',1,'2020-05-28 02:03:04'); --4
INSERT INTO messages(title,text,category,user_id, created_date)VALUES('title','Text','category',1,'2020-05-23 03:04:05'); --1
INSERT INTO messages(title,text,category,user_id, created_date)VALUES('title','Text','category',1,'2020-05-24 04:05:06'); --2
INSERT INTO messages(title,text,category,user_id, created_date)VALUES('title','Text','category',1,'2020-05-29 05:06:07'); --5
DemoControllerTest.java
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration //Ready to use context
@ContextConfiguration(locations = "classpath:spring/mvc-config.xml") //Specify which bean definition file to use
@Transactional //Defined for rollback after test
public class DemoControllerTest {
private MockMvc mockMvc;
@Autowired
private WebApplicationContext wac; //Prepare context
@Autowired
private JdbcTemplate jdbcTemplate;
@Before
public void setUp() {
executeScript("/META-INF/sql/insert_data.sql"); //SQL execution
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
@Test
public void test_1 Home screen display() throws Exception {
MvcResult mvcResult = mockMvc.perform(get("/home")) //Behavior of GET communication with perform
.andDo(print()) //Print on console
.andExpect(status().isOk()) //Check the status code
.andExpect(view().name("home")) //Does the View match?
.andExpect(model().attributeExists("allUserMessage")) //Check if the target model exists
.andExpect(model().attributeExists("userComment")) //Check if the target model exists
.andExpect(model().attributeExists("deleteCommentForm")) //Check if the target model exists
.andExpect(model().attributeExists("commentForm")) //Check if the target model exists
.andExpect(model().attributeExists("userMessageForm")) //Check if the target model exists
.andReturn(); //Return the result to mvcResult
ModelAndView mav = mvcResult.getModelAndView();
int[] expectMessageIdList = { 5, 2, 1, 4, 3 }; //For ascending order confirmation
@SuppressWarnings(value = "unchecked")
List<UserMessageForm> actualMessageList = ((List<UserMessageForm>) mav.getModel().get("allUserMessage"));
int expectMessageListSize = 5;
assertEquals(expectMessageListSize, actualMessageList.size()); //Does the created data match the List size of the displayed model?
for (int i = 0; i < 5; i++) {
assertEquals(expectMessageIdList[i], actualMessageList.get(i).getId()); //Is the message content in ascending order?
}
}
@Test
public void test_2_1 Can the login screen be displayed?() throws Exception {
mockMvc.perform(get("/login"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(model().attributeExists("loginForm"));
}
@Test
public void test_2_2 Can you log in?() throws Exception {
LoginForm loginForm = new LoginForm();
loginForm.setAccount("testuser");
loginForm.setPassword("password");
mockMvc.perform(post("/login").flashAttr("loginForm", loginForm))
.andDo(print())
.andExpect(view().name("redirect:/home")) //Transition destination when login is successful
.andExpect(status().isFound());
}
@Test
public void test_2_3 When the password is incorrect, an error is output and the login screen is displayed.() throws Exception {
LoginForm loginForm = new LoginForm();
loginForm.setAccount("testuser");
loginForm.setPassword("Wrong password");
MvcResult mvcResult = mockMvc.perform(post("/login")
.flashAttr("loginForm", loginForm))
.andDo(print())
.andExpect(view().name("login"))
.andExpect(status().isOk())
.andExpect(model().attributeHasErrors("loginForm")) //Is there an error in Model?
.andReturn();
ModelAndView mav = mvcResult.getModelAndView();
BindingResult result = (BindingResult) mav.getModel()
.get("org.springframework.validation.BindingResult.loginForm");
String actualErrorMessage = result.getFieldError("account").getDefaultMessage();
String expectErrorMessage = "Wrong login ID or password";
assertThat(expectErrorMessage, is(actualErrorMessage)); //Check the error message
}
@Test
public void test_2_4 When trying to log in with an account that does not exist, an error is output to the screen and the login screen is displayed.() throws Exception {
LoginForm loginForm = new LoginForm();
loginForm.setAccount("Non-existent account");
loginForm.setPassword("password");
MvcResult mvcResult = mockMvc.perform(post("/login")
.flashAttr("loginForm", loginForm))
.andDo(print())
.andExpect(status().isOk())
.andExpect(model().attributeHasErrors("loginForm")) //Is there an error in Model?
.andReturn();
ModelAndView mav = mvcResult.getModelAndView();
BindingResult result = (BindingResult) mav.getModel()
.get("org.springframework.validation.BindingResult.loginForm");
String actualErrorMessage = result.getFieldError("account").getDefaultMessage();
String expectErrorMessage = "Account does not exist";
assertThat(expectErrorMessage, is(actualErrorMessage)); //Check the error message
}
public void executeScript(String file) {
Resource resource = new ClassPathResource(file, getClass());
ResourceDatabasePopulator rdp = new ResourceDatabasePopulator();
rdp.addScript(resource);
rdp.setSqlScriptEncoding("UTF-8");
rdp.setIgnoreFailedDrops(true);
rdp.setContinueOnError(false);
Connection conn = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());
rdp.populate(conn);
}
}
It is just a unit test of the controller, and it does not consider acquiring and testing the rendering result on the View side (and no login filter etc. is applied). It seems that you can get the rendering result by using HtmlUnit, so I will list it on Qiita at another time.
Test data management by Java + Spring (3) [SpringBoot] How to write a controller test Spring test official document
Recommended Posts