您好,登錄后才能下訂單哦!
Java中怎么實現單元測試與集成測試,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
Maven測試代碼結構的組織
我們知道在Maven工程結構中“src/test”目錄是專門用于存放測試代碼的,但令人痛苦的是Maven的標準目錄結構只定義了這樣一個測試目錄,也就是說它本身是無法單獨區分單元測試代碼和集成測試代碼的,這也是為什么很多人會把UT和IT代碼同時寫到"src/test"目錄而導致“mvn test”難以跑過的原因。
那么有什么辦法可以友好地解決這個問題呢?在接下來的內容中我們以Maven構建Spring Boot項目為例來具體演示下在Maven中如何友好地分離UT及IT,具體步驟如下:
1)、首先我們創建一個基于Maven構建的Spring Boot項目,代碼結構如下圖所示:
如上圖所示,在規劃的目錄結構中我們將IT的代碼目錄及資源文件目錄單獨分離在“src/integration-test”目錄下,默認的“src/test”目錄還是作為存放UT代碼的目錄,而Maven在構建的過程中默認只運行UT代碼。這樣即便IT代碼由于網絡、環境等原因無法正常執行,但也不至于影響到UT代碼的運行。
2)、創建區分UT、IT代碼的Maven Profiles文件
默認情況下Maven是無法主動識別“src/test”目錄之外的測試代碼的,所以當我們將IT代碼抽象到"src/integration-test"目錄之后,需要通過編寫Maven Profiles文件來進行區分,具體示意圖如下:
如上圖所示,我們可以在與“src”目錄平行創建一個“profiles”的目錄,其中分別用“dev”、“integration-test”目錄中的config.properties文件來進行區分,其中dev目錄下的config.properties文件的內容為:
profile=dev
而integration-test目錄中的config.properties文件則為:
profile=integration-test
3)、通過pom.xml文件配置上述profiles文件生效規則
為了使得這些profiles文件生效,我們還需要在pom.xml文件中進行相應的配置。具體如下:
<!--定義關于區分集成測試及單元測試代碼的profiles--> <profiles> <!-- The Configuration of the development profile --> <profile> <id>dev</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <build.profile.id>dev</build.profile.id> <!--Only unit tests are run when the development profile is active--> <skip.integration.tests>true</skip.integration.tests> <skip.unit.tests>false</skip.unit.tests> </properties> </profile> <!-- The Configuration of the integration-test profile --> <profile> <id>integration-test</id> <properties> <build.profile.id>integration-test</build.profile.id> <!--Only integration tests are run when the integration-test profile is active--> <skip.integration.tests>false</skip.integration.tests> <skip.unit.tests>true</skip.unit.tests> </properties> </profile> </profiles>
上述內容先定義了區分dev及integration-test環境的的profile信息,接下來在build標簽中定義資源信息及相關plugin,具體如下:
<build> <finalName>${project.artifactId}</finalName> <!--步驟1:單元測試代碼、集成測試代碼分離--> <filters> <filter>profiles/${build.profile.id}/config.properties</filter> </filters> <resources> <resource> <filtering>false</filtering> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> <include>**/*.tld</include> <include>**/*.yml</include> </includes> </resource> <!--步驟2:通過Profile區分Maven集成測試代碼、單元測試代碼目錄--> <resource> <filtering>true</filtering> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> <include>**/*.tld</include> <include>**/*.yml</include> <include>**/*.sh</include> </includes> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- 步驟三:將源目錄和資源目錄添加到構建中 --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>3.1.0</version> <executions> <!-- Add a new source directory to our build --> <execution> <id>add-integration-test-sources</id> <phase>generate-test-sources</phase> <goals> <goal>add-test-source</goal> </goals> <configuration> <!-- Configures the source directory of our integration tests --> <sources> <source>src/integration-test/java</source> </sources> </configuration> </execution> <!-- Add a new resource directory to our build --> <execution> <id>add-integration-test-resources</id> <phase>generate-test-resources</phase> <goals> <goal>add-test-resource</goal> </goals> <configuration> <!-- Configures the resource directory of our integration tests --> <resources> <resource> <filtering>true</filtering> <directory>src/integration-test/resources</directory> <includes> <include>**/*.properties</include> </includes> </resource> </resources> </configuration> </execution> </executions> </plugin> <!--步驟四:Runs unit tests --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.18</version> <configuration> <!-- Skips unit tests if the value of skip.unit.tests property is true --> <skipTests>${skip.unit.tests}</skipTests> <!-- Excludes integration tests when unit tests are run --> <excludes> <exclude>**/IT*.java</exclude> </excludes> </configuration> </plugin> <!--步驟五:Runs integration tests --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>2.18</version> <executions> <execution> <id>integration-tests</id> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> <configuration> <skipTests>${skip.integration.tests}</skipTests> </configuration> </execution> </executions> </plugin> </plugins> </build>
到這里我們就完成了基于Maven構建的Spring Boot項目的UT及IT代碼目錄的分離配置,此時對UT代碼的執行還是通過默認“mvn test”命令,而集成測試代碼的運行則可以通過如下命令:
mvn clean verify -P integration-test
單元測試代碼示例
通過前面的配置操作就完成了單元測試、集成測試代碼目錄的分離設置。在后續的開發過程中只需要將相應的測試代碼寫在對應的測試目錄即可。接下來我們模擬一段業務邏輯并演示如何編寫其對應的UT代碼。具體如下:
如上圖所示,參考MVC三層規范,我們編寫了一個接口邏輯,該接口Controller層接收Http請求后調用Service層進行處理,而Service層處理邏輯時會調用Dao層操作數據庫,并將具體信息插入數據庫。
那么我們編寫單元測試(UT)代碼時,針對的是單獨的某個邏輯單元的測試,而不是從頭到位的整個邏輯,它的運行不應該依賴于任何網絡環境或其他組件,所有依賴的組件或網絡都應該先進行Mock。以單元測試TestServceImpl中的“saveTest”方法為例,其UT代碼編寫如下:
@RunWith(SpringRunner.class) @SpringBootTest(classes = TestServiceImpl.class) @ActiveProfiles("test") public class TestServiceImplTest { @Autowired TestServiceImpl testServiceImpl; @MockBean TestDao testDao; @Test public void saveTest() { //調用測試方法 testServiceImpl.saveTest("無敵碼農微信公眾號"); //驗證執行測試的邏輯中是否調用過addUser方法 verify(testDao).addUser(any()); } }
如上所示UT代碼,我們UT測試的主要對象為TestServiceImpl類,所以可以在@SpringBootTest注解中進行范圍指定。而@ActiveProfiles("test")則表示代碼中所依賴的系統參數,可以從測試資源目錄resouces/application-test.yml文件中獲得。
單元測試的主要目的是驗證單元代碼內的邏輯,對于所依賴的數據庫Dao組件并不是測試的范圍,但是沒有該Dao組件對象,UT代碼在執行的過程中也會報錯,所以一般會通過@MockBean注解進行組件Mock,以此解決UT測試過程中的代碼依賴問題。此時運行“mvn test”命令:
單元測試代碼得以正常執行!
集成測試代碼示例
在Spring Boot中UT代碼的編寫方式與IT代碼類似,但是其執行范圍是包括了整個上下文環境。我們以模擬從Controller層發起Http接口請求為例,來完整的測試整個接口的邏輯,并最終將數據存入數據庫。具體測試代碼如下:
@RunWith(SpringRunner.class) @SpringBootTest @ActiveProfiles("test") public class ITTestControllerTest { @Autowired TestController testController; @Test public void saveTest() { testController.saveTest("無敵碼農微信公眾號"); } }
可以看到對于集成測試代碼在@SpringBootTest中并沒有指定具體的類,它的默認執行范圍為整個應用的上下文環境。而代碼中的依賴組件由于整個應用上下文都會被啟動,所以依賴上并不會報錯,可以理解為是一個正常啟動的Spring Boot應用。
需要注意的是由于IT代碼的目錄有獨立的資源配置,所以相關的依賴配置,如數據庫等需要在“src/integration-test/resouces/application-test.yml”文件中單獨配置,例如:
spring: application: name: springboot-test-demo #數據庫邏輯 datasource: url: jdbc:mysql://127.0.0.1:3306/test username: root password: 123456 type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver separator: // server: port: 8080
此時運行集成測試命令“mvn clean verify -P integration-test”:
關于Java中怎么實現單元測試與集成測試問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。