In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-09 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article will explain in detail the example analysis of spring boot integration testing. The editor thinks it is very practical, so I share it for you as a reference. I hope you can get something after reading this article.
If you want to make it easy to test against API and easily integrate it into CI to verify each submission, then the IT that comes with spring boot is absolutely the best choice.
Quickly write a test Case
@ RunWith (SpringRunner.class) @ SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ ActiveProfiles ({Profiles.ENV_IT}) public class DemoIntegrationTest {@ Autowired private FooService fooService; @ Test public void test () {System.out.println ("tested");}}
SpringBootTest defines some configurations when running IT. The above code uses random ports, of course, you can also predefine ports, like this.
@ SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, properties = {"server.port=9990"})
ActiveProfiles enforces the use of IT's Profile, and in terms of best practice, the addresses of databases or other resource components configured by IT Profile should be isolated from the development or Staging environment. Because in many cases we need to clean up the test data when an IT has finished running.
You can find that such Case can use Autowired to inject any Service you want. This is because spring loads the entire context, which is the same as the actual running environment, including database, cache, and so on. If you feel that you don't need all the resources for testing, then delete the corresponding configuration in profile. This is a complete running environment, and the only difference is that it automatically shutdown when the use case runs out.
Test a Rest API
A library is highly recommended to be added to gradle
TestCompile 'io.rest-assured:rest-assured:3.0.3'
Support JsonPath, very easy to use, the specific document is stamped here
Sql (scripts = "/ testdata/users.sql") @ Testpublic void test001Login () {String username = "demo@demo.com"; String password = "demo"; JwtAuthenticationRequest request = new JwtAuthenticationRequest (username, password); Response response = given (). ContentType (ContentType.JSON) .body (request) .when (). Post ("/ auth/login"). Then () .statusCode (HttpStatus.OK.value ()) .extract () .response () AssertThat (response.path ("token"), is (IsNull.notNullValue ()); assertThat (response.path ("expiration"), is (IsNull.notNullValue ();}
Sql is used to perform sql insert test data before testing. Notice that what is passed in given (). Body () is a java object JwtAuthenticationRequest, because rest-assured will automatically serialize the object into a json string with jackson for you. Of course, you can also put the converted json into body, and the effect is the same.
The returned result is caught by a Response, and then you can use JsonPath to get the data from it for verification. Of course, there is a more intuitive way to get the complete response through response.asString (), and then deserialize it into a java object for verification.
At this point, the most basic IT is complete. By adding a step gradle test to Jenkins, you can test every time the code is submitted.
Some complicated situations
Data mix
This is the most likely to happen, a project has a lot of dev, each dev will write its own IT case, so what if there is an impact between the data. It is easy to understand, for example, in a scenario where batch writes are tested, and the final verification is to see if the amount of data written is 10w rows. Then another dev writes other case and happens to add a piece of data to this table, and the result becomes a 10w+1 row, so the bulk written case will not be able to escape.
To put an end to this, we use Class to empty the data after running one test at a time. Since it is a class-based operation, you can write a base class solution.
@ RunWith (SpringRunner.class) @ SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ ActiveProfiles ({Profiles.ENV_IT}) public abstract class BaseIntegrationTest {private static JdbcTemplate jdbcTemplate; @ Autowired public void setDataSource (DataSource dataSource) {jdbcTemplate = new JdbcTemplate (dataSource);} @ Value ("${local.server.port}") protected int port; @ Before public void setupEnv () {RestAssured.port = port; RestAssured.basePath = "/ api"; RestAssured.baseURI = "http://localhost"; RestAssured.config = RestAssured.config () .httpClient (HttpClientConfig.httpClientConfig () .httpMultipartMode (HttpMultipartMode.BROWSER_COMPATIBLE));} public void tearDownEnv () {given () .contentType (ContentType.JSON) .when () .post ("/ auth/logout");} @ AfterClass public static void cleanDB () throws SQLException {Resource resource = new ClassPathResource ("/ testdata/CleanDB.sql"); Connection connection = jdbcTemplate.getDataSource () .getConnection (); ScriptUtils.executeSqlScript (connection, resource) Connection.close ();}}
JdbcTemplate is used in @ AfterClass to execute a CleanDB.sql, which clears all test data in this way.
@ Value ("${local.server.port}") should also be mentioned, because the port is random, so Rest-Assured does not know which port the request is going to send to losthost. This problem is solved by using @ Value to get the current port number and setting it to RestAssured.port.
How to deal with common data
Running a full IT may take dozens of Class and hundreds of method, so what if some data is needed by all case and needs to be cleared only after all case has been run? In other words, this data cleanup is not based on classes, but on a single run. Such as initial user data, city database, etc.
We played a clever trick with the help of flyway
@ Configuration@ConditionalOnClass ({DataSource.class}) public class UpgradeAutoConfiguration {public static final String FLYWAY = "flyway"; @ Bean (name = FLYWAY) @ Profile ({ENV_IT}) public UpgradeService cleanAndUpgradeService (DataSource dataSource) {UpgradeService upgradeService = new FlywayUpgradeService (dataSource); try {upgradeService.cleanAndUpgrade ();} catch (Exception ex) {LOGGER.error ("Flyway failed!", ex);} return upgradeService;}}
You can see that when Profile is IT, flyway will drop all tables and re-execute each upgrade script in turn, thus creating a complete data table, which is, of course, empty. Under the test path of the project, add a large version of sql, so that flyway can insert shared test data, such as src/test/resources/db/migration/V999.0.1__Insert_Users.sql, to solve various data problems perfectly.
This is the end of this article on "sample Analysis of spring boot Integration testing". I hope the above content can be helpful to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.