Target - test all layers of SpringBoot REST application in isolation from external components.
Complexity - typical application uses database and makes calls to remote services.
Solutions:
a) Use spring-test support for integration tests. It actually starts whole app for you on random port. At the same time, all components of app can be wired into test for additional manipulations.
b) Use RestAssured to make calls to our application
c) Use RestTemplate to make remote calls and MockServer from spring-test to mock them
d) Use in-memory database. HSQLDB does the simulating job pretty well.
e) Use separate Spring profile to tweak app configuration
Here is a small example putting it all together:
Solutions:
a) Use spring-test support for integration tests. It actually starts whole app for you on random port. At the same time, all components of app can be wired into test for additional manipulations.
b) Use RestAssured to make calls to our application
c) Use RestTemplate to make remote calls and MockServer from spring-test to mock them
d) Use in-memory database. HSQLDB does the simulating job pretty well.
e) Use separate Spring profile to tweak app configuration
Here is a small example putting it all together:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.jayway.restassured.RestAssured | |
import org.springframework.beans.factory.annotation.Autowired | |
import org.springframework.beans.factory.annotation.Value | |
import org.springframework.boot.test.SpringApplicationConfiguration | |
import org.springframework.boot.test.WebIntegrationTest | |
import org.springframework.test.context.ActiveProfiles | |
import org.springframework.test.web.client.MockRestServiceServer | |
import org.springframework.web.client.RestTemplate | |
import spock.lang.Specification | |
import static com.jayway.restassured.RestAssured.given | |
import static com.jayway.restassured.http.ContentType.JSON | |
import static org.springframework.http.HttpMethod.* | |
import static org.springframework.http.MediaType.APPLICATION_JSON | |
import static org.springframework.test.web.client.match.MockRestRequestMatchers.* | |
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess | |
@SpringApplicationConfiguration(classes = Application) | |
@WebIntegrationTest(["server.port=0"]) //will actually start app on random port | |
@ActiveProfiles(["integration"]) //adapt some configuration for tests | |
class TrustlyPayoutSpec extends Specification { | |
@Value('${local.server.port}') | |
int port //random port chosen by spring test | |
@Autowired | |
Repository repository //we can wire any repository to run DB checks | |
@Autowired | |
RestTemplate remoteResourceRestTemplate //wire RestTemplate to instrument it with mock server | |
MockRestServiceServer mockRemoteResource | |
def setup() { | |
mockRemoteResource = MockRestServiceServer.createServer(remoteResourceRestTemplate) //instrument RestTemplate | |
RestAssured.port = port //configure RestAssured port | |
} | |
def "Some integration scenario"() { | |
expect: | |
//stub calls to remote resource using mock server | |
mockRemoteResource.expect(requestTo("https://example.com")) | |
.andExpect(method(PUT)) | |
.andExpect(jsonPath('$.state').value("TRANSFERRED")) | |
.andRespond(withSuccess( | |
""" {"status": "OK"} """ | |
, APPLICATION_JSON)) | |
//call our service using RestAssured | |
given().contentType(JSON).body(""" { "name": "John Doe" } """) | |
.when().post("/user") | |
.then().statusCode(CREATED.value()) | |
Thread.sleep(5000) //give some time for JMS messaging and async processing | |
User user = repository.findByName("John Doe") //check data in DB | |
//some assertions on DB data | |
mockRemoteResource.verify() | |
} | |
} |
Hello Aleksandr,
ReplyDeleteThe informative Article on Integration tests in SpringBoot without external dependencies is good. It gives detailed information about it .Thanks for Sharing the information unit testing and integration testing. Software Testing Services
Amplework Software Pvt. Ltd. offer flexible models to hire expert Swift app developers and programmers on hourly, part-time, or full-time contract basis at affordable cost.
ReplyDeleteProduct Design
MVP Development
DevOps Solutions
Mobile Application Development
Voice/Alexa App Development
IoT App Development