配置Checkstyle代码规范检查工具
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<configLocation>${basedir}/checkstyle.xml</configLocation>
<excludes>**/generate/**</excludes>
</configuration>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>10.7.0</version>
</dependency>
</dependencies>
</plugin>
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.1//EN"
"http://www.puppycrawl.com/dtds/configuration_1_1.dtd">
<module name="Checker">
<property name="localeLanguage" value="en"/>
<module name="NewlineAtEndOfFile">
<property name="lineSeparator" value="lf" />
</module>
<module name="FileTabCharacter">
<property name="fileExtensions" value="java,xml"/>
</module>
<module name="RegexpSingleline">
<!-- \s matches whitespace character, $ matches end of line. -->
<property name="format" value="\s+$"/>
<property name="message" value="Line has trailing spaces."/>
</module>
<module name="TreeWalker">
<module name="IllegalImport"/>
<module name="RedundantImport"/>
<module name="UnusedImports"/>
<module name="NeedBraces"/>
<module name="JavadocMethod">
<!-- 更早的版本里用的是scope -->
<property name="accessModifiers" value="public" />
</module>
<module name="ModifierOrder"/>
<module name="RedundantModifier"/>
<module name="UpperEll" />
<module name="LeftCurly"/>
<module name="NeedBraces"/>
<module name="RightCurly"/>
<module name="GenericWhitespace"/>
<module name="WhitespaceAfter"/>
<module name="NoWhitespaceBefore"/>
</module>
</module>
配置SpotBugs代码缺陷检查工具
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.7.3.0</version>
<configuration>
<excludeFilterFile>ignore.xml</excludeFilterFile>
</configuration>
<dependencies>
<!-- overwrite dependency on spotbugs if you want to specithe version of spotbugs -->
<dependency>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs</artifactId>
<version>4.7.3</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>spotbugs</id>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
<Match>
<Class name="~.*\.generate\..*"/>
</Match>
<Match>
<Bug pattern="EI_EXPOSE_REP2"/>
</Match>
</FindBugsFilter>
编写单元测试与jacoco测试覆盖率报告
单元测试
class CheckTelServiceTest {
public static AuthController.TelAndCode validParam = new AuthController.TelAndCode("13112345678", "000000");
public static AuthController.TelAndCode invalidParam = new AuthController.TelAndCode("23112345678", "000000");
@Test
void returnTrueIfValid() {
Assertions.assertTrue(new CheckTelService().verifyTelParams(validParam.getTel()));
}
@Test
void returnFalseIfInvalid() {
Assertions.assertFalse(new CheckTelService().verifyTelParams(invalidParam.getTel()));
}
}
jacoco
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.8</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>BUNDLE</element>
<limits>
<limit>
<counter>COMPLEXITY</counter>
<value>COVEREDRATIO</value>
<minimum>0.90</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
编写集成测试
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = ShopApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(locations = "classpath:application.yml")
public class CodeIntegrationTest {
public static ObjectMapper objectMapper = new ObjectMapper();
@Autowired
Environment env;
@Test
public void returnHttpOKIfParamsCorrect() throws IOException {
URL url = new URL(getUrl("/api/code") + "?tel=" + CheckTelServiceTest.validParam.getTel());
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.connect();
int status = con.getResponseCode();
Assertions.assertEquals(status, 200);
}
@Test
public void returnHttpBadIfParamsCorrect() throws IOException{
URL url = new URL(getUrl("/api/code") + "?tel=" + CheckTelServiceTest.invalidParam.getTel());
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.connect();
int status = con.getResponseCode();
Assertions.assertEquals(400, status);
}
@Test
public void getCodeAndLoginSuccess() throws IOException{
// 获取验证码
URL urlCode = new URL(getUrl("/api/code") + "?tel=" + CheckTelServiceTest.validParam.getTel());
HttpURLConnection conCode = (HttpURLConnection) urlCode.openConnection();
conCode.connect();
// 登录
URL urlLogin = new URL(getUrl("/api/login"));
HttpURLConnection conLogin = (HttpURLConnection) urlLogin.openConnection();
conLogin.setRequestMethod("POST");
conLogin.setDoOutput(true);
conLogin.setRequestProperty("Content-Type", MediaType.APPLICATION_JSON_VALUE);
DataOutputStream out = new DataOutputStream(conLogin.getOutputStream());
out.writeBytes(objectMapper.writeValueAsString(CheckTelServiceTest.validParam));
conLogin.connect();
int status = conLogin.getResponseCode();
Assertions.assertEquals(status, 200);
}
private String getUrl(String path) {
return "http://localhost:" + env.getProperty("local.server.port") + path;
}
}
插曲
the request was rejected because no multipart boundary was found
原因:设置了con.setRequestProperty("Content-Type", "multipart/form-data");
参考链接
- tomcat 10版本升级,
HttpServletResponse
从javax.servlet.http.HttpServletResponse
转移到了jakarta.servlet.http.HttpServletResponse