如何解决如何使用 springboot 和 sonarqube 测试控制器
所以我正在做我的第一个 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;
}
我的 build.gradle
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 之前阻止了它。因此,您的测试中不会执行任何代码行,这就是您看不到任何覆盖率的原因。
在测试您的 @Controller
类时,请查看 @WebMvcTest
和 MockMvc
,它是 great integration with Spring Security 来模拟经过身份验证的用户:
@Test
@WithMockUser("someUsername")
public void shouldAccessPartiesEndpoint() throws Exception {
this.mockMvc
.perform(delete("/parties"))
.andExpect(status().isOk());
}
对于您的 PartyService
,使用 Mockito 和 JUnit 进行单元测试就足够了。
如果您想在没有任何模拟的情况下编写 an integration test,请使用 @SpringBootTest
和例如使用 TestRestTemplate
或 WebTestClient
而不是 MockMvc
访问您的应用程序(使用模拟 servlet 环境)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。