Skip to content

MockMVC with PagingAndSortingRepository - put with Content-Type set to text/uri-list does not save relation #2350

Open
@mikebski

Description

@mikebski

I have some repositories and relations setup and it does not seem like MockMVC works with the text/uri-list PUT correctly.

I have it working with TestRestTemplates in a test where the server starts, but for some reason the MockMVC does not setup the relation properly. Is there additional test setup to use MockMVC with PagingAndSortingRepository?

Failing test (I get 404 for the last line):

package com.saisols.maint.integration

import com.fasterxml.jackson.databind.ObjectMapper
import com.saisols.maint.domain.Equipment
import com.saisols.maint.domain.Manufacturer
import com.saisols.maint.domain.Tag
import com.saisols.maint.domain.Vendor
import com.saisols.maint.getEquipment
import com.saisols.maint.getManufacturer
import com.saisols.maint.getTag
import com.saisols.maint.getVendor
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.ImportAutoConfiguration
import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
import org.springframework.test.web.servlet.result.MockMvcResultHandlers.print

@SpringBootTest
@AutoConfigureMockMvc
class MockMVCRESTTest {
    @Autowired
    private lateinit var mockMvc: MockMvc

    @Autowired private lateinit var objectMapper: ObjectMapper

    @Test
    fun testGetRoot(){
        this.mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk())
    }

    fun test_whenCreateManufacturer_thenSuccess_andReturnLocation(): String {
        val manufacturer = getManufacturer()
        val response = this.mockMvc.perform(post("/manufacturer").content(objectMapper.writeValueAsString(manufacturer)))
            .andDo(print()).andExpect(status().`is`(201)).andReturn()
        val location = response.response.getHeader("Location")
        assertNotNull(location)
        return location!!
    }

    fun test_whenCreateVendor_thenSuccess_andReturnLocation(): String {
        val vendor = getVendor()
        val response = this.mockMvc.perform(post("/vendor").content(objectMapper.writeValueAsString(vendor)))
            .andDo(print()).andExpect(status().`is`(201)).andReturn()
        val location = response.response.getHeader("Location")
        assertNotNull(location)
        return location!!
    }

    fun test_whenCreateTag_thenSuccess_andReturnLocation(): String {
        val response = this.mockMvc.perform(post("/tag").content(objectMapper.writeValueAsString(getTag())))
            .andDo(print()).andExpect(status().`is`(201)).andReturn()
        val location = response.response.getHeader("Location")
        assertNotNull(location)
        return location!!
    }

    fun test_whenCreateEquipment_thenSuccess_andReturnLocation(): String {
        val response = this.mockMvc.perform(post("/equipment").content(objectMapper.writeValueAsString(getEquipment())))
            .andDo(print()).andExpect(status().`is`(201)).andReturn()
        val location = response.response.getHeader("Location")
        assertNotNull(location)
        return location!!
    }
    
    @Test
    fun test_whenCreateVendorTag_thenCanFetchEach(){
        val vendorLocation = test_whenCreateVendor_thenSuccess_andReturnLocation()
        val vendor = objectMapper.readValue(this.mockMvc.perform(get(vendorLocation)).andExpect(status().
        `is`(200)).andReturn().response.contentAsString, Vendor::class.java)

        val tagLocation = test_whenCreateTag_thenSuccess_andReturnLocation()
        val tag = objectMapper.readValue(this.mockMvc.perform(get(tagLocation)).andExpect(status().
        `is`(200)).andReturn().response.contentAsString, Tag::class.java)

        val manufacturerLocation = test_whenCreateManufacturer_thenSuccess_andReturnLocation()
        val manufacturer = objectMapper.readValue(this.mockMvc.perform(get(manufacturerLocation)).andExpect(status().
        `is`(200)).andReturn().response.contentAsString, Manufacturer::class.java)

        val equipmentLocation = test_whenCreateEquipment_thenSuccess_andReturnLocation()
        val equipment = objectMapper.readValue(this.mockMvc.perform(get(equipmentLocation)).andExpect(status().
        `is`(200)).andReturn().response.contentAsString, Equipment::class.java)

        val equipmentManufacturerEndpoint = "${equipmentLocation}/manufacturer"
        var putResult = this.mockMvc.perform(
            put (equipmentManufacturerEndpoint).
        contentType("Content-Type:text/uri-list").content(manufacturerLocation))

       putResult.andExpect(status().`is`(200)) // Fails with 404
    }
}

Here is a passing test using TestRestTemplate:

package com.saisols.maint.integration

import com.saisols.maint.domain.Manufacturer
import com.saisols.maint.domain.Vendor
import com.saisols.maint.getEquipment
import com.saisols.maint.getManufacturer
import com.saisols.maint.getVendor
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment
import org.springframework.boot.test.web.client.TestRestTemplate
import org.springframework.boot.test.web.client.getForEntity
import org.springframework.boot.web.server.LocalServerPort
import org.springframework.http.HttpEntity
import org.springframework.http.HttpHeaders
import java.net.URI

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class HttpRequestTest {
    @LocalServerPort
    private var port: Int = 0

    @Autowired
    private lateinit var restTemplate: TestRestTemplate

    fun getUrlWithEndpoint(endpoint: String = ""): String {
        var slash = "/"
        if (endpoint.endsWith("/")) {
            slash = ""
        }
        return "http://localhost:${port}${slash}${endpoint}"
    }

    @Test
    fun rootShouldContainLinks() {
        val rootResponse = restTemplate.getForObject(
            getUrlWithEndpoint(),
            String::class.java
        )
        arrayOf("_links", "vendor", "manufacturer").forEach {
            assertThat(
                rootResponse
            ).contains(it)
        }
    }

    @Test
    fun testCrateEquipment() {
        createEquipment()
    }

    @Test
    fun testCrateManufacturer() {
        createEquipment()
    }

    @Test
    fun testAssociateEquipmentAndRelatedItems() {
        val equipmentLocation = createEquipment()
        val manufacturerLocation = createManufacturer()
        val vendorLocation = createVendor()

        val headers = HttpHeaders()
        headers.set("Content-Type", "text/uri-list")

        val entity: HttpEntity<String> = HttpEntity<String>(manufacturerLocation.toString(), headers)
        val equipmentManufacturer = "${equipmentLocation}/manufacturer"
        val associateResponse = restTemplate.put(
            equipmentManufacturer,
            entity
        )
        assertNotNull(associateResponse)

        val entityVendor: HttpEntity<String> = HttpEntity<String>(vendorLocation.toString(), headers)
        val equipmentVendor = "${equipmentLocation}/vendor"
        val associateResponse2 = restTemplate.put(
            equipmentVendor,
            entityVendor
        )
        assertNotNull(associateResponse2)

        val getResponseVendor = restTemplate.getForEntity(
            URI(equipmentVendor),
            Vendor::class.java)
        assertNotNull(getResponseVendor)
        assertEquals(getResponseVendor.statusCodeValue, 200)

        val getResponseManufacturer = restTemplate.getForEntity(
            URI(equipmentManufacturer),
            Manufacturer::class.java)
        assertNotNull(getResponseManufacturer)
        assertEquals(getResponseManufacturer.statusCodeValue, 200)
    }

    fun createVendor(): URI {
        val createResponse = restTemplate.postForLocation(
            getUrlWithEndpoint("/vendor"),
            getVendor()
        )
        assertNotNull(createResponse)
        return createResponse;
    }

    fun createManufacturer(): URI {
        val createResponse = restTemplate.postForLocation(
            getUrlWithEndpoint("/manufacturer"),
            getManufacturer()
        )
        assertNotNull(createResponse)
        return createResponse;
    }

    fun createEquipment(): URI {
        val createResponse = restTemplate.postForLocation(
            getUrlWithEndpoint("/equipment"),
            getEquipment()
        )
        assertNotNull(createResponse)
        return createResponse;
    }
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions