因此,我正在进行我的第一个Spring Boot项目,我一直在进行测试。我查了很多例子,但似乎都不管用。
这是我的控制器的当前测试:
@SpringBootTest
@AutoConfigureMockMvc
public class AddPartyTest {
@Autowired
private MockMvc mockMvc;
@Test
@DisplayName("Should Not give access to endpoint")
public void ShouldNotGiveAccess() throws Exception{
mockMvc.perform(MockMvcRequestBuilders.get("/parties"))
.andExpect(MockMvcResultMatchers.status().is(401));
}
这是可行的,但在sonarqube上,我发现我的代码覆盖率为0%,而我似乎找不到一个测试,它的覆盖率甚至超过了零。有谁能给我一个关于如何为控制器编写一个好的单元测试的例子,然后我就可以根据您的例子自己解决这个问题。
这是我的控制器:
@RestController
@RequestMapping("/parties")
public class PartyController {
@Autowired
PartyService partyService;
@GetMapping("")
public List<Party> list(){
return partyService.listAllParties();
}
@GetMapping("/{id}")
public ResponseEntity<PartyDto> get(@PathVariable Integer id){
try{
PartyDto partyDto = partyService.getParty(id);
return new ResponseEntity<>(partyDto, HttpStatus.OK);
} catch (NoSuchElementException e){
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@PostMapping("/")
public void add(@RequestBody PartyDto partyDto) throws ParseException {
partyService.saveParty(partyDto);
}
@PutMapping("/{id}")
public ResponseEntity<?> update(@RequestBody PartyDto partyDto, @PathVariable Integer id){
try{
PartyDto existParty = partyService.getParty(id);
partyDto.setId(id);
partyService.saveParty(partyDto);
return new ResponseEntity<>(HttpStatus.OK);
} catch (NoSuchElementException e){
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@DeleteMapping("/{id}")
public void delete(@PathVariable Integer id){
partyService.deleteParty(id);
}
@DeleteMapping("/")
public ResponseEntity<HttpStatus> deleteAllParties() {
try {
partyService.deleteAll();
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} catch (Exception e) {
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
这是我的服务(以防您需要):
@Service
@Transactional
public class PartyService {
@Autowired
private PartyRepository partyRepository;
@Autowired
private ModelMapper modelMapper;
public List<Party> listAllParties() {
return partyRepository.findAll();
}
public void saveParty(PartyDto partyDto){
Party party = convertToEntity(partyDto);
partyRepository.save(party);
}
public PartyDto getParty(Integer id) {
Party party = partyRepository.findById(id).orElse(null);
return convertToDto(party);
}
public void deleteParty(Integer id) {
partyRepository.deleteById(id);
}
public void deleteAll() {partyRepository.deleteAll();}
private PartyDto convertToDto(Party party) {
PartyDto partyDto = modelMapper.map(party, PartyDto.class);
return partyDto;
}
private Party convertToEntity(PartyDto partyDto) {
Party entity = new Party();
entity.setId(partyDto.getId());
entity.setName(partyDto.getName());
entity.setDescription(partyDto.getDescription());
entity.setIspartynational(partyDto.getIspartynational());
entity.setPartyLeader(partyDto.getPartyLeader());
return entity;
}
}
还有我的派对DTO
@Getter
@Setter
public class PartyDto {
private Integer id;
private String name;
private String description;
private Boolean ispartynational;
private PartyLeader partyLeader;
}
我的身材。格拉德尔
plugins {
id 'org.springframework.boot' version '2.4.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id "org.sonarqube" version "3.0"
id 'jacoco'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '15'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation('io.jsonwebtoken:jjwt:0.2')
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
compile 'junit:junit:4.12'
implementation 'org.modelmapper:modelmapper:2.4.1'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'mysql:mysql-connector-java'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
/**
* JUnit jupiter with mockito.
*/
testCompile group: 'org.mockito', name: 'mockito-junit-jupiter', version: '2.19.0'
/**
* Mockito for mocking.
*/
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.19.0'
}
test {
useJUnitPlatform()
}
如果您需要我的派对模型或存储库,请发表评论,我会添加它们!提前感谢!
现有测试验证匿名用户是否获得HTTP 401响应。MockMvc请求没有到达控制器,因为之前Spring Security会阻止它。因此,没有任何代码行作为测试的一部分执行,这就是为什么您看不到任何覆盖。
当要测试您的控制器类时,请看一下WebMvcTest和MockMvc,它与Spring Security集成得很好,可以模拟经过身份验证的用户:
@Test
@WithMockUser("someUsername")
public void shouldAccessPartiesEndpoint() throws Exception {
this.mockMvc
.perform(delete("/parties"))
.andExpect(status().isOk());
}
对于您的PartyService,使用Mockito和JUnit进行单元测试就足够了。
如果您想编写没有任何模拟的集成测试,请使用SpringBootTest,例如,使用TestRestTemplate或WebTestClient访问您的应用程序,而不是MockMvc(使用模拟servlet环境)。
我有下一个Rest控制器 我将Spring Security用于以下配置: 我想为我的控制器编写单元测试。我写了下一个测试,但是它们工作得不好: 当我开始测试时,我得到了状态404。如果在安全配置中删除@EnableGlobalmetodSecurity(prePostEnable=true),测试正在工作,但不工作@PreAuthorize。我有一些问题: 如果prespenabled=true
如何为RestController,Service和DAO层编写JUnit测试用例? 我试过 如何验证rest控制器和其他层中的CRUD方法?
问题内容: 初始化JavaFX运行时的正确方法是什么,以便您可以对使用并发工具和的控制器进行单元测试(使用JUnit)? 从该方法调用会导致死锁。如果未调用,则会引发以下错误: 后续:这是我根据@SergeyGrinev的建议一直使用的主题。 问题答案: 调用由是正确的做法。请注意,这不会将控制权返回给调用代码。因此,您必须将其包装到中。 7年后的更新: 使用TestFX!它将以适当的方式进行启动
问题内容: 我正在使用spring 3.2.0和junit 4 这是我需要测试的控制器方法 spring-servlet config is: This is my test class : 如何使用MockMvc测试此方法? 问题答案: 你可以使用以下注释来使用应用程序调度程序servlet xml。以下示例使用路径/ mysessiontest设置了一些会话属性并期望返回某个视图来命中控制器:
我的SpringBoot应用程序中有一个控制器: 我想在mocks的帮助下,将其与服务分开进行测试。如何实施?
我有一个生成屏幕截图的类: 我的应用程序是用创建的,我需要对它进行测试。但我得到 我的测试: 我试图防止无头异常: 我使用的是spring启动版本1.5.6。 但这无济于事。我得到日志: java.awt.HeadlessException在sun.awt.HeadlesStoolKit.GetScreenSize(headlesStoolKit.java:284)在org.robinhood.i