微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 springboot 和 sonarqube 测试控制器

如何解决如何使用 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 类时,请查看 @WebMvcTestMockMvc,它是 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 和例如使用 TestRestTemplateWebTestClient 而不是 MockMvc 访问您的应用程序(使用模拟 servlet 环境)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。