It seems pass when a run the test individually but fine when fair when running the class .I have tried to use @Before and @After annotatoon.And only the Dirtiescontext most fit my case.My question is any alternative for dirtiescontext(too slow) or any method can suit my case?
My test code:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
//@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
@AutoConfigureMockMvc
class UserCoreControllerTest {
@Autowired
private UserRepository userRepository;
@Autowired
private UserCoreService userCoreService;
@Autowired
private ObjectMapper objectMapper;
@Autowired
private MockMvc mockMvc;
/*
*//* @BeforeTestMethod
public void setUp(){
System.out.println("begin");
userRepository.save(mockUser());
}
@AfterTestMethod
public void tearOff(){
System.out.println("end");
userRepository.deleteById(1);
}
*/
private User mockUser(){
User user= new User(0,"admin","admin",null,null,"yl","sd"
,"434","dsf",null,4,2,new ArrayList<>());
user.getApplications().add(mockJobOrder("job1title","b"));
user.getApplications().add(mockJobOrder("job2title","d"));
return user;
}
private JobOrder mockJobOrder(String title,String des){
return new JobOrder(0,1,title,des,null,null,0,2,false,0,null);
}
@Test
void getProfile() throws Exception {
userRepository.save(mockUser());
mockMvc.perform(get("/UserJob/getProfile/{id}", 1)
.accept(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.username")
.value("admin"))
.andDo(print());
}
@Test
void getUserByName() throws Exception {
userRepository.save(mockUser());
mockMvc.perform(get("/UserJob/get/Byusername/{username}", "admin")
.accept(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.password").value("admin"));
//if cant found user
MvcResult whatever = mockMvc.perform(get("/UserJob/get/Byusername/{username}", "whatever")
.accept(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isOk())
.andReturn();
Assertions.assertEquals("",whatever.getResponse().getContentAsString());
}
@Test
void updateUser() throws Exception {
userRepository.save(mockUser());
User updated=new User(1,"alex","admin",null,null,"yl","sd"
,"434","dsf",null,4,2,null);
String request=objectMapper.writeValueAsString(updated);
MvcResult mvcResult=mockMvc.perform(MockMvcRequestBuilders.put("/UserJob/updateuser")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON_VALUE)
.content(request)
)
.andExpect(status().isOk())
.andDo(print())
.andReturn();
Assertions.assertEquals("Successful update",mvcResult.getResponse().getContentAsString());
mockMvc.perform(get("/UserJob/getProfile/{id}", 1)
.accept(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$.username")
.value("alex"))
.andDo(print());
}
@Test
void showApplicationshistory() throws Exception {
userRepository.save(mockUser());
mockMvc.perform(get("/UserJob/application/history/{id}", 1)
.accept(MediaType.APPLICATION_JSON_VALUE)
)
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].title").value("job1title"))
.andExpect(jsonPath("$[1].title").value("job2title"))
.andDo(print());
}
@Test
void addUser() throws Exception {
User user=mockUser();
user.setUsername("tom");
String request=objectMapper.writeValueAsString(user);
mockMvc.perform(MockMvcRequestBuilders.post("/UserJob/add/user")
.contentType(MediaType.APPLICATION_JSON)
.content(request)
.accept(MediaType.APPLICATION_JSON_VALUE))
.andExpect(status().isOk())
.andExpect(jsonPath("$.username").value("tom"));
}
Application properties(i test it on a real database with drop-create)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=*
spring.datasource.password=*
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.defer-datasource-initialization=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.sql.init.mode=always
logging.level.root=INFO
I guess that the test are failing because of some user constraints - since you insert the user a multiple times here.
There are multiple solutions for that.
repository.deleteAll()
or truncate the whole db with some sql statements.Just as a side information: You can also use testcontainers instead of having a persistente database locally. See https://www.testcontainers.org/ or even better: a wrapper library around it: https://github.com/PlaytikaOSS/testcontainers-spring-boot