我正在爲我的Spring啓動應用程序Rest控制器編寫集成測試。@Transcational測試類影響事務服務層的工作方式
當我使用@Transactional
註釋測試類時,它不能按預期工作,而當我刪除註釋時,它傳遞的很好。
使用
@Transactional
在測試類是否意味着絕對 沒有被寫入到數據庫?我的其他測試工作正常! 他們或多或少地做同樣的工作。他們寫入/更新/讀取,但是這個測試測試了一個刪除端點。如果使用@Transactional註釋測試類意味着無法控制數據持久性,爲什麼人們甚至在測試中使用它?我將實體經理注入了測試課程,名爲
flush
和clear
,但沒有幫助。即使數據沒有寫入數據庫,它們仍然存在,對吧?不調用
repository.delete
應該從持久化上下文中刪除該項目?不影響db(刪除)的代碼位於服務層。它是從我正在測試的Controller中調用的,而不是測試類。我希望它能夠工作,無論測試課是否註冊了
@Transacational
。
注服務層是@Transactional
這是在服務層和由控制器調用。它在測試中不叫表格。
public void delete(long groupId, String username) {
Group group = this.loadById(groupId);
User user = userService.loadByUsername(username);
groupRepository.delete(groupId);
}
編輯1
失敗的測試代碼:
/*
* Deleting a group shouldn't delete the members of that group
*/
@Test
public void testDeleteGroupWithMembers() throws Exception {
Principal mockPrincipal = Mockito.mock(Principal.class);
Mockito.when(mockPrincipal.getName()).thenReturn(DUMMY_USERNAME);
User admin = userTestingUtil.createUser(DUMMY_USERNAME, DUMMY_USER_NAME, null, null);
Group group = groupTestingUtil.createGroup(DUMMY_GROUP_NAME, DUMMY_GROUP_DESCRIPTION, DUMMY_IMAGE_ID, admin);
User member = userTestingUtil.createUser("[email protected]", "testUser1" , null, null);
group.addMember(member);
RequestBuilder requestBuilder = MockMvcRequestBuilders
.delete(GROUP_ENDPOINT_URL + group.getId())
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.principal(mockPrincipal);
MvcResult result = mockMvc.perform(requestBuilder).andReturn();
MockHttpServletResponse response = result.getResponse();
int status = response.getStatus();
String content = response.getContentAsString();
Assert.assertEquals("wrong response status", 200, status);
Assert.assertEquals("wrong response content", "", content);
//This test fails, as the group is not yet deleted from the repo
Assert.assertEquals("there should be no group left", 0, Lists.newArrayList(groupRepository.findAll()).size());
Assert.assertEquals("wrong number of users exist", 2, Lists.newArrayList(userRepository.findAll()).size());
Assert.assertTrue("admin shouldn't get deleted when deleting a group", userRepository.findById(admin.getId()) != null);
Assert.assertTrue("group members shouldn't get deleted when deleting a group", userRepository.findById(member.getId()) != null);
}
的測試在同一個測試類的工作代碼:
@Test
public void testCreateGroup() throws Exception {
Principal mockPrincipal = Mockito.mock(Principal.class);
Mockito.when(mockPrincipal.getName()).thenReturn(DUMMY_USERNAME);
User user = userTestingUtil.createUser(DUMMY_USERNAME, DUMMY_USER_NAME, null, null);
JSONObject jo = new JSONObject();
jo.put(NAME_FIELD_NAME, DUMMY_GROUP_NAME);
jo.put(DESCRIPTION_FIELD_NAME, DUMMY_GROUP_DESCRIPTION);
jo.put(IMAGE_FIELD_NAME, DUMMY_IMAGE);
String testGroupJson = jo.toString();
RequestBuilder requestBuilder = MockMvcRequestBuilders
.post(GROUP_ENDPOINT_URL).content(testGroupJson)
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.principal(mockPrincipal);
MvcResult result = mockMvc.perform(requestBuilder).andReturn();
MockHttpServletResponse response = result.getResponse();
int status = response.getStatus();
String content = response.getContentAsString();
List<Group> createdGroups = Lists.newArrayList(groupRepository.findAll());
Group createdGroup = createdGroups.get(0);
Assert.assertEquals("wrong response status", 200, status);
Assert.assertEquals("wrong response content", "", content);
Assert.assertEquals("wrong number of groups created", 1, createdGroups.size());
Assert.assertEquals("wrong group name", DUMMY_GROUP_NAME, createdGroup.getName());
Assert.assertEquals("wrong group description", DUMMY_GROUP_DESCRIPTION, createdGroup.getDescription());
Assert.assertEquals("wrong admin is assigned to the group", user.getId(), createdGroup.getAdmin().getId());
List<Group> groups = userTestingUtil.getOwnedGroups(user.getId());
Assert.assertEquals("wrong number of groups created for the admin", 1, groups.size());
Assert.assertEquals("wrong group is assigned to the admin", user.getOwnedGroups().get(0).getId(), createdGroup.getAdmin().getId());
Assert.assertTrue("image file was not created", CommonUtils.getImageFile(createdGroup.getImageId()).exists());
}
創建並刪除GroupService
中的方法:
public void create(String groupName, String description, String image, String username) throws IOException {
User user = userService.loadByUsername(username);
Group group = new Group();
group.setAdmin(user);
group.setName(groupName);
group.setDescription(description);
String imageId = CommonUtils.decodeBase64AndSaveImage(image);
if (imageId != null) {
group.setImageId(imageId);
}
user.addOwnedGroup(group);
groupRepository.save(group);
logger.debug("Group with name " + group.getName() + " and id " + group.getId() + " was created");
}
public void delete(long groupId, String username) {
Group group = this.loadById(groupId);
User user = userService.loadByUsername(username);
validateAdminAccessToGroup(group, user);
groupRepository.delete(groupId);
logger.debug("Group with id " + groupId + " was deleted");
}
爲休息控制器代碼:
/*
* Create a group
*/
@RequestMapping(path = "", method = RequestMethod.POST)
public void create(@RequestBody PostGroupDto groupDto, Principal principal, BindingResult result) throws IOException {
createGroupDtoValidator.validate(groupDto, result);
if (result.hasErrors()) {
throw new ValidationException(result.getFieldError().getCode());
}
groupService.create(groupDto.getName(), groupDto.getDescription(), groupDto.getImage(), principal.getName());
}
/*
* Delete a group
*/
@RequestMapping(path = "/{groupId}", method = RequestMethod.DELETE)
public void delete(@PathVariable long groupId, Principal principal) {
groupService.delete(groupId, principal.getName());
}
編輯2
我試圖刪除User
,而不是Group
,它並不能工作。在同樣的方法(組服務層的delete
方法)創建一個組的作品,但刪除不!
爲了保持謹慎,建議持久化上下文應該拋出一個異常,這表明你還沒有完全理解它是如何工作的。通常情況下,除非在調用delete方法之前事務已經開始(以及我使用的方式),否則不會從'User'中刪除'Group'。因爲如果'User'已經加載,最好保持雙向關係與數據庫同步,否則調用者將不得不調用'em.refresh(user)'來查看該組不再處於'用戶的列表(假設正確的級聯)。 –