-
Notifications
You must be signed in to change notification settings - Fork 10
Testing Java Spring applications
In our Java testing library there is a possibility to test web backend applications based on Spring library. Testing web backend applications written in Python (for example, using Django) is not yet supported.
First of all, this functionality is not available in Library Version 5. At the moment it exists only in the dev branch. To use this functionality you need to replace the current version of the library in gradle dependencies with 'com.github.hyperskill:hs-test:723b24a584891511ffde92a700da585a703ee13e'
.
In Spring tests you only need to override generate
function, not check
because each test will be tested differently. Each test will be assigned its own test function by calling the setCheckFunc
method.
Let's test some class named SpringDemoApplication
.
First of all, you need to extend SpringTest
class and pass this class to the constructor along with the port number on which you are going to run and test this Spring application.
import org.hyperskill.hstest.dev.mocks.web.response.HttpResponse;
import org.hyperskill.hstest.dev.stage.SpringTest;
import org.hyperskill.hstest.dev.testcase.CheckResult;
import org.hyperskill.hstest.dev.testcase.TestCase;
import springdemo.SpringDemoApplication;
import java.util.List;
public class DemoTest extends SpringTest {
public DemoTest() {
super(SpringDemoApplication.class, 8889);
}
}
Second, you need to add a special file with properties to allow shutting down the server externally. It could be done by specifying a resource folder in the user's build.gradle
(not in build.gradle
used for testing - user's build.gradle
is part of the user's solution for the stage).
plugins {
id 'org.springframework.boot' version '2.1.5.RELEASE'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
sourceSets.main.resources.srcDirs = ["src/resources"]
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
compile("org.springframework.boot:spring-boot-starter-web")
}
And by specifying properties file itself.
server.port=8889
management.endpoints.web.exposure.include=*
management.endpoint.shutdown.enabled=true
Let's imagine that on URL /api/user/
the Spring application should return a list of all users in the JSON format (in this case, there should be 2 users in the output). The test will look like this:
new TestCase<>().setCheckFunc((r, a) -> {
HttpResponse response = get("/api/user/").send();
if (response.getStatusCode() != 200) {
return CheckResult.FALSE("GET /api/user/ should respond with " +
"status code 200, responded: " + response.getStatusCode() + "\n\n" +
"Response body:\n" + response.getContent());
}
JsonElement json;
try {
json = response.getJson();
} catch (Exception ex) {
return CheckResult.FALSE("GET /api/user/ should return a valid JSON");
}
if (!json.isJsonArray()) {
return CheckResult.FALSE("GET /api/user/ should return an array of objects");
}
JsonArray array = json.getAsJsonArray();
if (array.size() != 2) {
return CheckResult.FALSE("GET /api/user/ should initially return 2 objects");
}
return CheckResult.TRUE;
}),
Notice the method get
- you can use it to send GET request to the tested application. You also can use post
, put
and delete
methods - they all declared in the SpringTest
class.
You can see an example with the post
method below (for example, an application should create a new user using POST /api/user/
and return a total number of users):
private String newUser = "{\n" +
" \"id\": 8,\n" +
" \"name\": \"NEW-USER\",\n" +
" \"email\": \"superuser@hyperskill.org\",\n" +
" \"skills\": [\n" +
" {\n" +
" \"name\": \"JAVA\"\n" +
" },\n" +
" {\n" +
" \"name\": \"KOTLIN\"\n" +
" }\n" +
" ]\n" +
"}";
...
new TestCase<>().setCheckFunc((r, a) -> {
HttpResponse response = post("/api/user/", newUser).send();
if (response.getStatusCode() != 200) {
return CheckResult.FALSE("POST /api/user/ should respond with " +
"status code 200, responded: " + response.getStatusCode() + "\n\n" +
"Response body:\n" + response.getContent());
}
int totalUsers;
try {
totalUsers = Integer.parseInt(response.getContent());
} catch (NumberFormatException ex) {
return CheckResult.FALSE("POST /api/user/ " +
"should create a user and return a number of users. No number was in the response.");
}
if (totalUsers != 3) {
return CheckResult.FALSE("POST /api/user/ " +
"should create a user and return a number of users. " +
"Expected to receive \"3\", received: \"" + totalUsers + "\"");
}
return CheckResult.TRUE;
}),
- Home
- About
- Initial setup
- Writing tests
- Guidelines for writing tests
- Outcomes of testing
- Generating and checking
- Presentation error
- Checking JSON
- Testing solutions written in different languages
- Creating Hyperskill problems based on hs-test
- Testing Java Swing applications
- Testing Java Spring applications
- Testing Ktor applications