Writing Integration Tests for a REST API With Kotlin and JUnit 5: Writing Data
After we have finished this lesson, we understand how we can an write integration tests for a REST API that writes data to the database.
This lessons assumes that:
- You can write integration tests for Spring web applications with JUnit 4
- You can create a request builder class that sends HTTP requests to the system under test
- You can write unit tests for controller functions which writes data data to the database
- You can configure the system under test when you are writing integration tests for a REST APIwith Kotlin and JUnit 5
Get the source code from Github
Introduction to the System Under Test
During this lesson we will write integration tests for a controller function which processes POST requests send to the path: ‘/api/task’. This function inserts a new task into the database and returns the information of the created task as JSON.
When the system under tests saves a new task to the database, it follows these steps:
- Read the information of the created task from the request body and validate the information. If validation fails, return the HTTP status code 400 (bad request) and return the validation errors as JSON.
- Get the authenticated user (a
UserDetailsobject) from the security context. - Save a new task to the database.
- Return the HTTP status code 201 (created) and return the information of the created task as JSON.
The source code of our controller class looks as follows:
1import org.springframework.beans.factory.annotation.Autowired
2import org.springframework.http.HttpStatus
3import org.springframework.security.core.annotation.AuthenticationPrincipal
4import org.springframework.web.bind.annotation.*
5import javax.validation.Valid
6
7@RestController
8@RequestMapping("/api/task")
9open class TaskCrudController(
10 @Autowired private val service: TaskCrudService
11) {
12
13 @RequestMapping(method = [RequestMethod.POST])
14 @ResponseStatus(HttpStatus.CREATED)
15 fun create(
16 @RequestBody @Valid input: CreateTaskDTO,
17 @AuthenticationPrincipal loggedInUser: LoggedInUser
18 ): TaskDTO {
19 return service.create(input, loggedInUser)
20 }
21}
The validation errors are processed by the TaskErrorHandler class. Its implementation doesn’t belong to the scope of this lesson, but it’s useful to know what kind of a JSON document is returned to the client if validation fails. For example, if the client tries to create a new task that has no title, the following JSON document is returned to the client:
1{
2 "fieldErrors":[
3 {
4 "field":"title",
5 "errorCode":"NotBlank"
6 }
7 ]
8}
The CreateTaskDTO class contains the information of the created task and specifies the validation rules which are used to validate the input data provided to the system under test. Its source code looks as follows:
1data class CreateTaskDTO(
2 @field: NotBlank
3 @field: Size(max = 100)
4 val title: String?,
5 @field: Size(max = 500)
6 val description: String?)
After the system under test has inserted a new task into the database, it returns the following JSON document back to client:
1{
2 "creator": {
3 "name": "John Doe",
4 "userId": 1
5 },
6 "description": "This lesson talks about integration testing",
7 "id": 1,
8 "modifier": {
9 "name": "John Doe",
10 "userId": 1
11 },
12 "status": "OPEN",
13 "tags": [],
14 "title": "Write lesson"
15}
Next, we will configure the system under test.
Configuring the System Under Test
During this lesson we will write integration tests which verify that the system under test is working as expected when a normal user provides valid information to the system under test. We can configure the system under test by following these steps:
First, we have to add one constant to our test class. This constant specifies the id of the created task. After we have added this constant to our test class, its source code looks as follows:
1import org.junit.jupiter.api.DisplayName
2import org.springframework.beans.factory.annotation.Autowired
3import org.springframework.test.web.servlet.MockMvc
4
5@WebIntegrationTest
6@DisplayName("Create a new task by using valid information")
7class CreateNewTaskWithValidInformationApiTest (
8 @Autowired private val mockMvc: MockMvc
9) {
10
11 companion object {
12
13 private val NEXT_FREE_ID = 1L
14 }
15
16 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
17}
Second, we have to add a private read-only property to our test class. This property contains an IdColumnReset object that can reset the auto-increment columns of the specified database tables. We can add this property to our test class by following these steps:
- Add a private read-only property called
jdbcTemplateto our test class and inject the value of this property by using constructor injection. This property contains aNamedParameterJdbcTemplateobject which allows us to reset the auto-increment column of thetasksdatabase table. - Add the
IdColumnResetproperty to our test class.
After we have added this property to our test class, its source code looks as follows:
1import org.junit.jupiter.api.DisplayName
2import org.springframework.beans.factory.annotation.Autowired
3import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
4import org.springframework.test.web.servlet.MockMvc
5
6@WebIntegrationTest
7@DisplayName("Create a new task by using valid information")
8class CreateNewTaskWithValidInformationApiTest (
9 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
10 @Autowired private val mockMvc: MockMvc
11) {
12
13 companion object {
14
15 private val NEXT_FREE_ID = 1L
16 }
17
18 private val idColumnReset = IdColumnReset(jdbcTemplate)
19
20 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
21}
Third, we have to add a private read-only property to our test class. This property contains the input that’s provided to the system under test. After we have added this property to our test class, its source code looks as follows:
1import org.junit.jupiter.api.DisplayName
2import org.springframework.beans.factory.annotation.Autowired
3import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
4import org.springframework.test.web.servlet.MockMvc
5
6@WebIntegrationTest
7@DisplayName("Create a new task by using valid information")
8class CreateNewTaskWithValidInformationApiTest (
9 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
10 @Autowired private val mockMvc: MockMvc
11) {
12
13 companion object {
14
15 private val NEXT_FREE_ID = 1L
16 }
17
18 private val idColumnReset = IdColumnReset(jdbcTemplate)
19
20 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
21
22 private val INPUT = CreateTaskDTO(
23 description = Tasks.WriteLesson.DESCRIPTION,
24 title = Tasks.WriteLesson.TITLE
25 )
26}
The Tasks class is a constant class that contains the test data which is used by our integration tests. Its source code looks as follows:
1class Tasks {
2
3 class WriteLesson {
4
5 companion object {
6
7 const val ID = 2L;
8 const val CREATOR_ID = 1L
9 const val DESCRIPTION = "This lesson talks about integration testing";
10 const val TITLE = "Write lesson"
11 val STATUS = TaskStatus.OPEN
12 }
13 }
14}
Fourth, we have to write a setup function that’s run before a test function is run. Our implementation of this function must reset the auto-increment column of the tasks database table. After we have written this function, the source code of our test class looks as follows:
1import org.junit.jupiter.api.BeforeEach
2import org.junit.jupiter.api.DisplayName
3import org.springframework.beans.factory.annotation.Autowired
4import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
5import org.springframework.test.web.servlet.MockMvc
6
7@WebIntegrationTest
8@DisplayName("Create a new task by using valid information")
9class CreateNewTaskWithValidInformationApiTest (
10 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
11 @Autowired private val mockMvc: MockMvc
12) {
13
14 companion object {
15
16 private val NEXT_FREE_ID = 1L
17 }
18
19 private val idColumnReset = IdColumnReset(jdbcTemplate)
20
21 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
22
23 private val INPUT = CreateTaskDTO(
24 description = Tasks.WriteLesson.DESCRIPTION,
25 title = Tasks.WriteLesson.TITLE
26 )
27
28 @BeforeEach
29 fun resetIdColumn() {
30 idColumnReset.resetIdColumns("tasks")
31 }
32}
Fifth, we have to create the inner class that contains the test functions which ensure that the system test is working as expected when a normal user provides valid information to the system under test.
After we have created this inner class, the source code of our test class looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
4import org.junit.jupiter.api.BeforeEach
5import org.junit.jupiter.api.DisplayName
6import org.junit.jupiter.api.Nested
7import org.springframework.beans.factory.annotation.Autowired
8import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
9import org.springframework.security.test.context.support.WithUserDetails
10import org.springframework.test.web.servlet.MockMvc
11
12@WebIntegrationTest
13@DisplayName("Create a new task by using valid information")
14class CreateNewTaskWithValidInformationApiTest (
15 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
16 @Autowired private val mockMvc: MockMvc
17) {
18
19 companion object {
20
21 private val NEXT_FREE_ID = 1L
22 }
23
24 private val idColumnReset = IdColumnReset(jdbcTemplate)
25
26 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
27
28 private val INPUT = CreateTaskDTO(
29 description = Tasks.WriteLesson.DESCRIPTION,
30 title = Tasks.WriteLesson.TITLE
31 )
32
33 @BeforeEach
34 fun resetIdColumn() {
35 idColumnReset.resetIdColumns("tasks")
36 }
37
38 @Nested
39 @WebIntegrationTest
40 @DatabaseSetup(value = [
41 "/com/testwithspring/master/users.xml",
42 "/com/testwithspring/master/no-tasks-and-tags.xml"
43 ])
44 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
45 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
46 @DisplayName("When the user is John Doe")
47 inner class WhenUserIsJohnDoe {
48
49 }
50}
The DbUnit data set (users.xml) which inserts the user data into our database looks as follows:
1<dataset>
2 <user_accounts id="1"
3 email_address="john.doe@gmail.com"
4 is_enabled="true"
5 name="John Doe"
6 password="user"
7 role="ROLE_USER"/>
8 <user_accounts id="2"
9 email_address="anne.admin@gmail.com"
10 is_enabled="true"
11 name="Anne Admin"
12 password="admin"
13 role="ROLE_ADMIN"/>
14</dataset>
The DbUnit data set (no-tasks-and-tags.xml) which ensures that our database has no tasks and tags looks as follows:
1<dataset>
2 <tasks/>
3 <tags/>
4 <tasks_tags/>
5</dataset>
The Users class is a constant class which contains the test data found from the user_accounts table. The relevant part of its source code looks as follows:
1class Users {
2
3 class JohnDoe {
4
5 companion object {
6 const val ID = 1L
7 const val EMAIL_ADDRESS = "john.doe@gmail.com"
8 const val NAME = "John Doe"
9 }
10 }
11}
Let’s move on and write integration tests for our controller function.
Writing Integration Tests for Our Controller Function
We can write integration tests for our controller function by following these steps:
First, we have verify that the system under test uses the next free id when it inserts a new task into the database. After we have written our test function, its source code looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.annotation.ExpectedDatabase
4import com.github.springtestdbunit.assertion.DatabaseAssertionMode
5import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
6import org.junit.jupiter.api.BeforeEach
7import org.junit.jupiter.api.DisplayName
8import org.junit.jupiter.api.Nested
9import org.junit.jupiter.api.Test
10import org.springframework.beans.factory.annotation.Autowired
11import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
12import org.springframework.security.test.context.support.WithUserDetails
13import org.springframework.test.web.servlet.MockMvc
14
15@WebIntegrationTest
16@DisplayName("Create a new task by using valid information")
17class CreateNewTaskWithValidInformationApiTest (
18 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
19 @Autowired private val mockMvc: MockMvc
20) {
21
22 companion object {
23
24 private val NEXT_FREE_ID = 1L
25 }
26
27 private val idColumnReset = IdColumnReset(jdbcTemplate)
28
29 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
30
31 private val INPUT = CreateTaskDTO(
32 description = Tasks.WriteLesson.DESCRIPTION,
33 title = Tasks.WriteLesson.TITLE
34 )
35
36 @BeforeEach
37 fun resetIdColumn() {
38 idColumnReset.resetIdColumns("tasks")
39 }
40
41 @Nested
42 @WebIntegrationTest
43 @DatabaseSetup(value = [
44 "/com/testwithspring/master/users.xml",
45 "/com/testwithspring/master/no-tasks-and-tags.xml"
46 ])
47 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
48 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
49 @DisplayName("When the user is John Doe")
50 private inner class WhenUserIsJohnDoe {
51
52 @Test
53 @DisplayName("Should use the next free id when a new task is saved to the database")
54 @ExpectedDatabase(
55 value = "/com/testwithspring/master/task/create-task-id-expected.xml",
56 assertionMode = DatabaseAssertionMode.NON_STRICT
57 )
58 fun shouldUseNextFreeIdWhenNewTaskIsSavedToDatabase() {
59 requestBuilder.create(INPUT)
60 }
61 }
62}
The DbUnit data set (create-task-id-expected.xml) which ensures that system under test uses the next free id when it saves a new task to the database looks as follows:
1<dataset>
2 <tasks id="1"/>
3</dataset>
Second, we have to ensure that the system under test inserts the correct lifecycle column values into the database. After we have written our test function, its source code looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.annotation.ExpectedDatabase
4import com.github.springtestdbunit.assertion.DatabaseAssertionMode
5import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
6import org.junit.jupiter.api.BeforeEach
7import org.junit.jupiter.api.DisplayName
8import org.junit.jupiter.api.Nested
9import org.junit.jupiter.api.Test
10import org.springframework.beans.factory.annotation.Autowired
11import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
12import org.springframework.security.test.context.support.WithUserDetails
13import org.springframework.test.web.servlet.MockMvc
14
15@WebIntegrationTest
16@DisplayName("Create a new task by using valid information")
17class CreateNewTaskWithValidInformationApiTest (
18 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
19 @Autowired private val mockMvc: MockMvc
20) {
21
22 companion object {
23
24 private val NEXT_FREE_ID = 1L
25 }
26
27 private val idColumnReset = IdColumnReset(jdbcTemplate)
28
29 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
30
31 private val INPUT = CreateTaskDTO(
32 description = Tasks.WriteLesson.DESCRIPTION,
33 title = Tasks.WriteLesson.TITLE
34 )
35
36 @BeforeEach
37 fun resetIdColumn() {
38 idColumnReset.resetIdColumns("tasks")
39 }
40
41 @Nested
42 @WebIntegrationTest
43 @DatabaseSetup(value = [
44 "/com/testwithspring/master/users.xml",
45 "/com/testwithspring/master/no-tasks-and-tags.xml"
46 ])
47 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
48 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
49 @DisplayName("When the user is John Doe")
50 inner class WhenUserIsJohnDoe {
51
52 @Test
53 @DisplayName("Should insert correct lifecycle column values into the database")
54 @ExpectedDatabase(
55 value = "create-task-lifecycle-columns-johndoe-expected.xml",
56 assertionMode = DatabaseAssertionMode.NON_STRICT
57 )
58 fun shouldInsertCorrectLifecycleColumnValuesIntoDatabase() {
59 requestBuilder.create(INPUT)
60 }
61 }
62}
The DbUnit data set (create-task-lifecycle-columns-johndoe-expected.xml) which ensures that the system under test inserts the correct lifecycle column values into the database looks as follows:
1<dataset>
2 <tasks assignee_id="[null]"
3 closer_id="[null]"
4 creator_id="1"
5 modifier_id="1"/>
6</dataset>
Third, we have to verify that the system under test saves the correct status and resolution to the database. After we have written our test function, its source code looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.annotation.ExpectedDatabase
4import com.github.springtestdbunit.assertion.DatabaseAssertionMode
5import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
6import org.junit.jupiter.api.BeforeEach
7import org.junit.jupiter.api.DisplayName
8import org.junit.jupiter.api.Nested
9import org.junit.jupiter.api.Test
10import org.springframework.beans.factory.annotation.Autowired
11import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
12import org.springframework.security.test.context.support.WithUserDetails
13import org.springframework.test.web.servlet.MockMvc
14
15@WebIntegrationTest
16@DisplayName("Create a new task by using valid information")
17class CreateNewTaskWithValidInformationApiTest (
18 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
19 @Autowired private val mockMvc: MockMvc
20) {
21
22 companion object {
23
24 private val NEXT_FREE_ID = 1L
25 }
26
27 private val idColumnReset = IdColumnReset(jdbcTemplate)
28
29 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
30
31 private val INPUT = CreateTaskDTO(
32 description = Tasks.WriteLesson.DESCRIPTION,
33 title = Tasks.WriteLesson.TITLE
34 )
35
36 @BeforeEach
37 fun resetIdColumn() {
38 idColumnReset.resetIdColumns("tasks")
39 }
40
41 @Nested
42 @WebIntegrationTest
43 @DatabaseSetup(value = [
44 "/com/testwithspring/master/users.xml",
45 "/com/testwithspring/master/no-tasks-and-tags.xml"
46 ])
47 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
48 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
49 @DisplayName("When the user is John Doe")
50 inner class WhenUserIsJohnDoe {
51
52 @Test
53 @DisplayName("Should save the correct status and resolution to the database")
54 @ExpectedDatabase(
55 value = "/com/testwithspring/master/task/create-task-status-expected.xml",
56 assertionMode = DatabaseAssertionMode.NON_STRICT
57 )
58 fun shouldSaveCorrectStatusAndResolutionToDatabase() {
59 requestBuilder.create(INPUT)
60 }
61 }
62}
The DbUnit data set (create-task-status-expected.xml) which ensures that the system under test saves the correct status and resolution to the database looks as follows:
1<dataset>
2 <tasks resolution="[null]"
3 status="OPEN"/>
4</dataset>
Fourth, we have to ensure that the system under test inserts the correct title and description into the database. After we have written our test function, its source code looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.annotation.ExpectedDatabase
4import com.github.springtestdbunit.assertion.DatabaseAssertionMode
5import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
6import org.junit.jupiter.api.BeforeEach
7import org.junit.jupiter.api.DisplayName
8import org.junit.jupiter.api.Nested
9import org.junit.jupiter.api.Test
10import org.springframework.beans.factory.annotation.Autowired
11import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
12import org.springframework.security.test.context.support.WithUserDetails
13import org.springframework.test.web.servlet.MockMvc
14
15@WebIntegrationTest
16@DisplayName("Create a new task by using valid information")
17class CreateNewTaskWithValidInformationApiTest (
18 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
19 @Autowired private val mockMvc: MockMvc
20) {
21
22 companion object {
23
24 private val NEXT_FREE_ID = 1L
25 }
26
27 private val idColumnReset = IdColumnReset(jdbcTemplate)
28
29 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
30
31 private val INPUT = CreateTaskDTO(
32 description = Tasks.WriteLesson.DESCRIPTION,
33 title = Tasks.WriteLesson.TITLE
34 )
35
36 @BeforeEach
37 fun resetIdColumn() {
38 idColumnReset.resetIdColumns("tasks")
39 }
40
41 @Nested
42 @WebIntegrationTest
43 @DatabaseSetup(value = [
44 "/com/testwithspring/master/users.xml",
45 "/com/testwithspring/master/no-tasks-and-tags.xml"
46 ])
47 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
48 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
49 @DisplayName("When the user is John Doe")
50 inner class WhenUserIsJohnDoe {
51
52 @Test
53 @DisplayName("Should insert the correct title and description to the database")
54 @ExpectedDatabase(
55 value = "/com/testwithspring/master/task/create-task-title-description-expected.xml",
56 assertionMode = DatabaseAssertionMode.NON_STRICT
57 )
58 fun shouldInsertCorrectTitleAndDescriptionToDatabase() {
59 requestBuilder.create(INPUT)
60 }
61 }
62}
The DbUnit data set (create-task-title-description-expected.xml) which ensures that the system under test inserts the correct title and description into the database looks as follows:
1<dataset>
2 <tasks description="This lesson talks about integration testing"
3 title="Write lesson"/>
4</dataset>
Fifth, we have to verify that the system under test creates a task that has no tags. After we have written our test function, its source code looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.annotation.ExpectedDatabase
4import com.github.springtestdbunit.assertion.DatabaseAssertionMode
5import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
6import org.junit.jupiter.api.BeforeEach
7import org.junit.jupiter.api.DisplayName
8import org.junit.jupiter.api.Nested
9import org.junit.jupiter.api.Test
10import org.springframework.beans.factory.annotation.Autowired
11import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
12import org.springframework.security.test.context.support.WithUserDetails
13import org.springframework.test.web.servlet.MockMvc
14
15@WebIntegrationTest
16@DisplayName("Create a new task by using valid information")
17class CreateNewTaskWithValidInformationApiTest (
18 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
19 @Autowired private val mockMvc: MockMvc
20) {
21
22 companion object {
23
24 private val NEXT_FREE_ID = 1L
25 }
26
27 private val idColumnReset = IdColumnReset(jdbcTemplate)
28
29 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
30
31 private val INPUT = CreateTaskDTO(
32 description = Tasks.WriteLesson.DESCRIPTION,
33 title = Tasks.WriteLesson.TITLE
34 )
35
36 @BeforeEach
37 fun resetIdColumn() {
38 idColumnReset.resetIdColumns("tasks")
39 }
40
41 @Nested
42 @WebIntegrationTest
43 @DatabaseSetup(value = [
44 "/com/testwithspring/master/users.xml",
45 "/com/testwithspring/master/no-tasks-and-tags.xml"
46 ])
47 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
48 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
49 @DisplayName("When the user is John Doe")
50 inner class WhenUserIsJohnDoe {
51
52 @Test
53 @DisplayName("Should create a task that has no tags")
54 @ExpectedDatabase(
55 value = "/com/testwithspring/master/task/create-task-tags-expected.xml",
56 assertionMode = DatabaseAssertionMode.NON_STRICT
57 )
58 fun shouldCreateTaskThatHasNoTags() {
59 requestBuilder.create(INPUT)
60 }
61 }
62}
The DbUnit data set (create-task-tags-expected.xml) which verifies that the system under test creates a task that has no tags looks as follows:
1<dataset>
2 <tags/>
3 <tasks_tags/>
4</dataset>
Sixth, we have to ensure that the system under test returns the HTTP status code 201. After we have written our test function, its source code looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
4import org.junit.jupiter.api.BeforeEach
5import org.junit.jupiter.api.DisplayName
6import org.junit.jupiter.api.Nested
7import org.junit.jupiter.api.Test
8import org.springframework.beans.factory.annotation.Autowired
9import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
10import org.springframework.security.test.context.support.WithUserDetails
11import org.springframework.test.web.servlet.MockMvc
12import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
13
14@WebIntegrationTest
15@DisplayName("Create a new task by using valid information")
16class CreateNewTaskWithValidInformationApiTest (
17 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
18 @Autowired private val mockMvc: MockMvc
19) {
20
21 companion object {
22
23 private val NEXT_FREE_ID = 1L
24 }
25
26 private val idColumnReset = IdColumnReset(jdbcTemplate)
27
28 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
29
30 private val INPUT = CreateTaskDTO(
31 description = Tasks.WriteLesson.DESCRIPTION,
32 title = Tasks.WriteLesson.TITLE
33 )
34
35 @BeforeEach
36 fun resetIdColumn() {
37 idColumnReset.resetIdColumns("tasks")
38 }
39
40 @Nested
41 @WebIntegrationTest
42 @DatabaseSetup(value = [
43 "/com/testwithspring/master/users.xml",
44 "/com/testwithspring/master/no-tasks-and-tags.xml"
45 ])
46 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
47 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
48 @DisplayName("When the user is John Doe")
49 inner class WhenUserIsJohnDoe {
50
51 @Test
52 @DisplayName("Should return the HTTP status code created")
53 fun shouldReturnHttpStatusCodeCreated() {
54 requestBuilder.create(INPUT)
55 .andExpect(status().isCreated)
56 }
57 }
58}
Seventh, we have to ensure that the system under test returns the information of the created task as JSON. After we have written our test function, its source code looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
4import org.junit.jupiter.api.BeforeEach
5import org.junit.jupiter.api.DisplayName
6import org.junit.jupiter.api.Nested
7import org.junit.jupiter.api.Test
8import org.springframework.beans.factory.annotation.Autowired
9import org.springframework.http.MediaType
10import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
11import org.springframework.security.test.context.support.WithUserDetails
12import org.springframework.test.web.servlet.MockMvc
13import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content
14
15@WebIntegrationTest
16@DisplayName("Create a new task by using valid information")
17class CreateNewTaskWithValidInformationApiTest (
18 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
19 @Autowired private val mockMvc: MockMvc
20) {
21
22 companion object {
23
24 private val NEXT_FREE_ID = 1L
25 }
26
27 private val idColumnReset = IdColumnReset(jdbcTemplate)
28
29 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
30
31 private val INPUT = CreateTaskDTO(
32 description = Tasks.WriteLesson.DESCRIPTION,
33 title = Tasks.WriteLesson.TITLE
34 )
35
36 @BeforeEach
37 fun resetIdColumn() {
38 idColumnReset.resetIdColumns("tasks")
39 }
40
41 @Nested
42 @WebIntegrationTest
43 @DatabaseSetup(value = [
44 "/com/testwithspring/master/users.xml",
45 "/com/testwithspring/master/no-tasks-and-tags.xml"
46 ])
47 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
48 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
49 @DisplayName("When the user is John Doe")
50 inner class WhenUserIsJohnDoe {
51
52 @Test
53 @DisplayName("Should return the information of the created task as Json")
54 fun shouldReturnInformationOfCreatedTaskAsJson() {
55 requestBuilder.create(INPUT)
56 .andExpect(content().contentType(MediaType.APPLICATION_JSON))
57 }
58 }
59}
Eigth, we have to verify that the system under test returns the information of the created task. After we have written our test function, its source code looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
4import org.hamcrest.Matchers.equalTo
5import org.junit.jupiter.api.BeforeEach
6import org.junit.jupiter.api.DisplayName
7import org.junit.jupiter.api.Nested
8import org.junit.jupiter.api.Test
9import org.springframework.beans.factory.annotation.Autowired
10import org.springframework.http.MediaType
11import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
12import org.springframework.security.test.context.support.WithUserDetails
13import org.springframework.test.web.servlet.MockMvc
14import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
15
16@WebIntegrationTest
17@DisplayName("Create a new task by using valid information")
18class CreateNewTaskWithValidInformationApiTest (
19 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
20 @Autowired private val mockMvc: MockMvc
21) {
22
23 companion object {
24
25 private val NEXT_FREE_ID = 1L
26 }
27
28 private val idColumnReset = IdColumnReset(jdbcTemplate)
29
30 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
31
32 private val INPUT = CreateTaskDTO(
33 description = Tasks.WriteLesson.DESCRIPTION,
34 title = Tasks.WriteLesson.TITLE
35 )
36
37 @BeforeEach
38 fun resetIdColumn() {
39 idColumnReset.resetIdColumns("tasks")
40 }
41
42 @Nested
43 @WebIntegrationTest
44 @DatabaseSetup(value = [
45 "/com/testwithspring/master/users.xml",
46 "/com/testwithspring/master/no-tasks-and-tags.xml"
47 ])
48 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
49 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
50 @DisplayName("When the user is John Doe")
51 inner class WhenUserIsJohnDoe {
52
53 @Test
54 @DisplayName("Should return the information of the created task")
55 fun shouldReturnInformationOfCreatedTask() {
56 requestBuilder.create(INPUT)
57 .andExpect(jsonPath("$.id", equalTo(NEXT_FREE_ID.toInt())))
58 }
59 }
60}
Ninth, we have ensure that the system under test returns a task that has no assignee. After we have written our test function, its source code looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
4import org.hamcrest.Matchers.nullValue
5import org.junit.jupiter.api.BeforeEach
6import org.junit.jupiter.api.DisplayName
7import org.junit.jupiter.api.Nested
8import org.junit.jupiter.api.Test
9import org.springframework.beans.factory.annotation.Autowired
10import org.springframework.http.MediaType
11import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
12import org.springframework.security.test.context.support.WithUserDetails
13import org.springframework.test.web.servlet.MockMvc
14import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
15
16@WebIntegrationTest
17@DisplayName("Create a new task by using valid information")
18class CreateNewTaskWithValidInformationApiTest (
19 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
20 @Autowired private val mockMvc: MockMvc
21) {
22
23 companion object {
24
25 private val NEXT_FREE_ID = 1L
26 }
27
28 private val idColumnReset = IdColumnReset(jdbcTemplate)
29
30 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
31
32 private val INPUT = CreateTaskDTO(
33 description = Tasks.WriteLesson.DESCRIPTION,
34 title = Tasks.WriteLesson.TITLE
35 )
36
37 @BeforeEach
38 fun resetIdColumn() {
39 idColumnReset.resetIdColumns("tasks")
40 }
41
42 @Nested
43 @WebIntegrationTest
44 @DatabaseSetup(value = [
45 "/com/testwithspring/master/users.xml",
46 "/com/testwithspring/master/no-tasks-and-tags.xml"
47 ])
48 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
49 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
50 @DisplayName("When the user is John Doe")
51 inner class WhenUserIsJohnDoe {
52
53 @Test
54 @DisplayName("Should return a task that has no assignee")
55 fun shouldReturnTaskThatHasNoAssignee() {
56 requestBuilder.create(INPUT)
57 .andExpect(jsonPath("$.assignee", nullValue()))
58 }
59 }
60}
Tenth, we have to verify that the system under test returns a task that has no closer. After we have written our test function, its source code looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
4import org.hamcrest.Matchers.nullValue
5import org.junit.jupiter.api.BeforeEach
6import org.junit.jupiter.api.DisplayName
7import org.junit.jupiter.api.Nested
8import org.junit.jupiter.api.Test
9import org.springframework.beans.factory.annotation.Autowired
10import org.springframework.http.MediaType
11import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
12import org.springframework.security.test.context.support.WithUserDetails
13import org.springframework.test.web.servlet.MockMvc
14import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
15
16@WebIntegrationTest
17@DisplayName("Create a new task by using valid information")
18class CreateNewTaskWithValidInformationApiTest (
19 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
20 @Autowired private val mockMvc: MockMvc
21) {
22
23 companion object {
24
25 private val NEXT_FREE_ID = 1L
26 }
27
28 private val idColumnReset = IdColumnReset(jdbcTemplate)
29
30 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
31
32 private val INPUT = CreateTaskDTO(
33 description = Tasks.WriteLesson.DESCRIPTION,
34 title = Tasks.WriteLesson.TITLE
35 )
36
37 @BeforeEach
38 fun resetIdColumn() {
39 idColumnReset.resetIdColumns("tasks")
40 }
41
42 @Nested
43 @WebIntegrationTest
44 @DatabaseSetup(value = [
45 "/com/testwithspring/master/users.xml",
46 "/com/testwithspring/master/no-tasks-and-tags.xml"
47 ])
48 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
49 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
50 @DisplayName("When the user is John Doe")
51 inner class WhenUserIsJohnDoe {
52
53 @Test
54 @DisplayName("Should return a task that has no closer")
55 fun shouldReturnTaskThatHasNoCloser() {
56 requestBuilder.create(INPUT)
57 .andExpect(jsonPath("$.closer", nullValue()))
58 }
59 }
60}
Eleventh, we have to ensure that the system under test returns the information of the person who created the task. After we have written our test function, its source code looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
4import org.hamcrest.Matchers.equalTo
5import org.junit.jupiter.api.BeforeEach
6import org.junit.jupiter.api.DisplayName
7import org.junit.jupiter.api.Nested
8import org.junit.jupiter.api.Test
9import org.springframework.beans.factory.annotation.Autowired
10import org.springframework.http.MediaType
11import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
12import org.springframework.security.test.context.support.WithUserDetails
13import org.springframework.test.web.servlet.MockMvc
14import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
15
16@WebIntegrationTest
17@DisplayName("Create a new task by using valid information")
18class CreateNewTaskWithValidInformationApiTest (
19 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
20 @Autowired private val mockMvc: MockMvc
21) {
22
23 companion object {
24
25 private val NEXT_FREE_ID = 1L
26 }
27
28 private val idColumnReset = IdColumnReset(jdbcTemplate)
29
30 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
31
32 private val INPUT = CreateTaskDTO(
33 description = Tasks.WriteLesson.DESCRIPTION,
34 title = Tasks.WriteLesson.TITLE
35 )
36
37 @BeforeEach
38 fun resetIdColumn() {
39 idColumnReset.resetIdColumns("tasks")
40 }
41
42 @Nested
43 @WebIntegrationTest
44 @DatabaseSetup(value = [
45 "/com/testwithspring/master/users.xml",
46 "/com/testwithspring/master/no-tasks-and-tags.xml"
47 ])
48 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
49 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
50 @DisplayName("When the user is John Doe")
51 inner class WhenUserIsJohnDoe {
52
53 @Test
54 @DisplayName("Should return the the information of the person who created the task")
55 fun shouldReturnCorrectCreator() {
56 requestBuilder.create(INPUT)
57 .andExpect(jsonPath(
58 "$.creator.name",
59 equalTo(Users.JohnDoe.NAME))
60 )
61 .andExpect(jsonPath(
62 "$.creator.userId",
63 equalTo(Users.JohnDoe.ID.toInt()))
64 )
65 }
66 }
67}
Twelfth, we have to ensure that the system under test returns the information of the person who modified the task. After we have written our test function, its source code looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
4import org.hamcrest.Matchers.equalTo
5import org.junit.jupiter.api.BeforeEach
6import org.junit.jupiter.api.DisplayName
7import org.junit.jupiter.api.Nested
8import org.junit.jupiter.api.Test
9import org.springframework.beans.factory.annotation.Autowired
10import org.springframework.http.MediaType
11import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
12import org.springframework.security.test.context.support.WithUserDetails
13import org.springframework.test.web.servlet.MockMvc
14import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
15
16@WebIntegrationTest
17@DisplayName("Create a new task by using valid information")
18class CreateNewTaskWithValidInformationApiTest (
19 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
20 @Autowired private val mockMvc: MockMvc
21) {
22
23 companion object {
24
25 private val NEXT_FREE_ID = 1L
26 }
27
28 private val idColumnReset = IdColumnReset(jdbcTemplate)
29
30 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
31
32 private val INPUT = CreateTaskDTO(
33 description = Tasks.WriteLesson.DESCRIPTION,
34 title = Tasks.WriteLesson.TITLE
35 )
36
37 @BeforeEach
38 fun resetIdColumn() {
39 idColumnReset.resetIdColumns("tasks")
40 }
41
42 @Nested
43 @WebIntegrationTest
44 @DatabaseSetup(value = [
45 "/com/testwithspring/master/users.xml",
46 "/com/testwithspring/master/no-tasks-and-tags.xml"
47 ])
48 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
49 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
50 @DisplayName("When the user is John Doe")
51 inner class WhenUserIsJohnDoe {
52
53 @Test
54 @DisplayName("Should return the the information of the person who modified the task")
55 fun shouldReturnCorrectModifier() {
56 requestBuilder.create(INPUT)
57 .andExpect(jsonPath(
58 "$.modifier.name",
59 equalTo(Users.JohnDoe.NAME))
60 )
61 .andExpect(jsonPath(
62 "$.modifier.userId",
63 equalTo(Users.JohnDoe.ID.toInt()))
64 )
65 }
66 }
67}
Thirteenth, we have to verify that the system under test returns the correct description and title. After we have written our test function, its source code looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
4import org.hamcrest.Matchers.equalTo
5import org.junit.jupiter.api.BeforeEach
6import org.junit.jupiter.api.DisplayName
7import org.junit.jupiter.api.Nested
8import org.junit.jupiter.api.Test
9import org.springframework.beans.factory.annotation.Autowired
10import org.springframework.http.MediaType
11import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
12import org.springframework.security.test.context.support.WithUserDetails
13import org.springframework.test.web.servlet.MockMvc
14import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
15
16@WebIntegrationTest
17@DisplayName("Create a new task by using valid information")
18class CreateNewTaskWithValidInformationApiTest (
19 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
20 @Autowired private val mockMvc: MockMvc
21) {
22
23 companion object {
24
25 private val NEXT_FREE_ID = 1L
26 }
27
28 private val idColumnReset = IdColumnReset(jdbcTemplate)
29
30 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
31
32 private val INPUT = CreateTaskDTO(
33 description = Tasks.WriteLesson.DESCRIPTION,
34 title = Tasks.WriteLesson.TITLE
35 )
36
37 @BeforeEach
38 fun resetIdColumn() {
39 idColumnReset.resetIdColumns("tasks")
40 }
41
42 @Nested
43 @WebIntegrationTest
44 @DatabaseSetup(value = [
45 "/com/testwithspring/master/users.xml",
46 "/com/testwithspring/master/no-tasks-and-tags.xml"
47 ])
48 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
49 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
50 @DisplayName("When the user is John Doe")
51 inner class WhenUserIsJohnDoe {
52
53 @Test
54 @DisplayName("Should return the correct description and title")
55 fun shouldReturnCorrectDescriptionAndTitle() {
56 requestBuilder.create(INPUT)
57 .andExpect(jsonPath(
58 "$.description",
59 equalTo(Tasks.WriteLesson.DESCRIPTION))
60 )
61 .andExpect(jsonPath(
62 "$.title",
63 equalTo(Tasks.WriteLesson.TITLE))
64 )
65 }
66 }
67}
Fourteenth, we have to ensure that the system under test returns an open task. After we have written our test function, its source code looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
4import org.hamcrest.Matchers.equalTo
5import org.hamcrest.Matchers.nullValue
6import org.junit.jupiter.api.BeforeEach
7import org.junit.jupiter.api.DisplayName
8import org.junit.jupiter.api.Nested
9import org.junit.jupiter.api.Test
10import org.springframework.beans.factory.annotation.Autowired
11import org.springframework.http.MediaType
12import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
13import org.springframework.security.test.context.support.WithUserDetails
14import org.springframework.test.web.servlet.MockMvc
15import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
16
17@WebIntegrationTest
18@DisplayName("Create a new task by using valid information")
19class CreateNewTaskWithValidInformationApiTest (
20 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
21 @Autowired private val mockMvc: MockMvc
22) {
23
24 companion object {
25
26 private val NEXT_FREE_ID = 1L
27 }
28
29 private val idColumnReset = IdColumnReset(jdbcTemplate)
30
31 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
32
33 private val INPUT = CreateTaskDTO(
34 description = Tasks.WriteLesson.DESCRIPTION,
35 title = Tasks.WriteLesson.TITLE
36 )
37
38 @BeforeEach
39 fun resetIdColumn() {
40 idColumnReset.resetIdColumns("tasks")
41 }
42
43 @Nested
44 @WebIntegrationTest
45 @DatabaseSetup(value = [
46 "/com/testwithspring/master/users.xml",
47 "/com/testwithspring/master/no-tasks-and-tags.xml"
48 ])
49 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
50 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
51 @DisplayName("When the user is John Doe")
52 inner class WhenUserIsJohnDoe {
53
54 @Test
55 @DisplayName("Should return an open task")
56 fun shouldReturnOpenTask() {
57 requestBuilder.create(INPUT)
58 .andExpect(jsonPath("$.resolution", nullValue()))
59 .andExpect(jsonPath(
60 "$.status",
61 equalTo(Tasks.WriteLesson.STATUS.name))
62 )
63 }
64 }
65}
Fifteenth, we have to verify that the system under test returns a task that has no tags. After we have written our test function, its source code looks as follows:
1import com.github.springtestdbunit.annotation.DatabaseSetup
2import com.github.springtestdbunit.annotation.DbUnitConfiguration
3import com.github.springtestdbunit.dataset.ReplacementDataSetLoader
4import org.hamcrest.Matchers.hasSize
5import org.junit.jupiter.api.BeforeEach
6import org.junit.jupiter.api.DisplayName
7import org.junit.jupiter.api.Nested
8import org.junit.jupiter.api.Test
9import org.springframework.beans.factory.annotation.Autowired
10import org.springframework.http.MediaType
11import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
12import org.springframework.security.test.context.support.WithUserDetails
13import org.springframework.test.web.servlet.MockMvc
14import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
15
16@WebIntegrationTest
17@DisplayName("Create a new task by using valid information")
18class CreateNewTaskWithValidInformationApiTest (
19 @Autowired private val jdbcTemplate: NamedParameterJdbcTemplate,
20 @Autowired private val mockMvc: MockMvc
21) {
22
23 companion object {
24
25 private val NEXT_FREE_ID = 1L
26 }
27
28 private val idColumnReset = IdColumnReset(jdbcTemplate)
29
30 private val requestBuilder = TaskCrudRequestBuilder(mockMvc)
31
32 private val INPUT = CreateTaskDTO(
33 description = Tasks.WriteLesson.DESCRIPTION,
34 title = Tasks.WriteLesson.TITLE
35 )
36
37 @BeforeEach
38 fun resetIdColumn() {
39 idColumnReset.resetIdColumns("tasks")
40 }
41
42 @Nested
43 @WebIntegrationTest
44 @DatabaseSetup(value = [
45 "/com/testwithspring/master/users.xml",
46 "/com/testwithspring/master/no-tasks-and-tags.xml"
47 ])
48 @DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader::class)
49 @WithUserDetails(Users.JohnDoe.EMAIL_ADDRESS)
50 @DisplayName("When the user is John Doe")
51 inner class WhenUserIsJohnDoe {
52
53 @Test
54 @DisplayName("Should return a task that has no tags")
55 fun shouldReturnTaskThatHasNoTags() {
56 requestBuilder.create(INPUT)
57 .andExpect(jsonPath("$.tags", hasSize<Any>(0)))
58 }
59 }
60}
We can now write integration tests for a REST API that writes data to the database. Let’s summarize what we learned from this lesson.
Summary
This lesson has taught us two things:
- We can reset the auto-increment column of a database table by using the
NamedParameterJdbcTemplateclass. - If we use small DbUnit data sets, we can write integration tests which assert one logical concept.