mardi 28 mai 2019

Pass parameters to a get with spring mvc test

I am using spring rest docs to generate the documentation of an API. My problem is that inside the get I have some objects which are created from other ones, so I need to mock these objects with are the base to create others ones. I'm not pretty sure how can I achieve that. This is what I am doing now:

My Controller looks like this:

import com.espn.api.platform.model.*
import com.espn.csemobile.espnapp.context.*
import com.espn.csemobile.espnapp.context.common.RequestBasedSWIDContext
import com.espn.csemobile.espnapp.context.common.RequestBasedSeeAllContext
import com.espn.csemobile.espnapp.context.common.RequestBasedUIDContext
import com.espn.csemobile.espnapp.models.browseplayer.BrowsePlayerResponse
import com.espn.csemobile.espnapp.services.browseplayer.BrowsePlayerServiceRepresentable
import com.espn.csemobile.espnapp.services.browseplayer.contexts.RequestBrowsePlayerContext
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
import rx.Single

@Controller
@ProductApi(
        id = "v1_browse_player",
        title = "Browse Player (v1)",
        description = "")
class BrowsePlayerController(private val transaction: Transaction,private val apiRequest: ApiRequest) {

    @Autowired
    lateinit var browsePlayerService: BrowsePlayerServiceRepresentable

    @GetRequest(
            path = "/v1/browse/players",
            timeToLive = 300,
            queries = [
                QueryParameter(name = "swid", required = true),
                QueryParameter(name = "uid"),
                QueryParameter(name = "seeAll", type = java.lang.Boolean::class),
                QueryParameter(name = "lang", required = true),
                QueryParameter(name = "region", required = true),
                QueryParameter(name = "version", required = true, type = Integer::class),
                QueryParameter(name = "appName", required = true),
                QueryParameter(name = "platform", required = true)
            ]
    )
    @GetMapping()
    fun processBrowsePlayerRequest(transaction: Transaction, apiRequest: ApiRequest): Single<BrowsePlayerResponse?> {
        val applicationContext = RequestBasedApplicationContext(apiRequest)
        val standardContext = RequestBasedStandardContext(
                RequestBasedVersionContext(apiRequest),
                applicationContext,
                RequestBasedEditionContext(apiRequest, applicationContext),
                RequestBasedPlatformContext(apiRequest),
                transaction
        )
        val swidContext = RequestBasedSWIDContext(apiRequest)
        val uidContext = if (checkUIDPresent(apiRequest)) RequestBasedUIDContext(apiRequest) else null
        val seeAllContext = RequestBasedSeeAllContext(apiRequest)
        val requestBrowsePlayerContext = RequestBrowsePlayerContext(standardContext, swidContext, uidContext, seeAllContext, apiRequest)
        return browsePlayerService.getEntitiesBrowse(requestBrowsePlayerContext)
    }

    private fun checkUIDPresent(apiRequest: ApiRequest): Boolean =
            apiRequest.parameters["uid"] != null
}

The issue is for example when I want to create this object: val swidContext = RequestBasedSWIDContext(apiRequest) which depends from the apiRequest one.

My test is just like this:

import com.espn.api.platform.model.ApiRequest
import com.espn.api.platform.model.Transaction
import com.espn.csemobile.espnapp.context.StandardContext
import com.espn.csemobile.espnapp.context.common.SWIDContext
import com.espn.csemobile.espnapp.context.common.SeeAllContext
import com.espn.csemobile.espnapp.context.common.UIDContext
import com.espn.csemobile.espnapp.models.UID
import com.espn.csemobile.espnapp.models.browseplayer.*
import com.espn.csemobile.espnapp.services.browseplayer.BrowsePlayerServiceRepresentable
import com.espn.csemobile.espnapp.services.browseplayer.contexts.RequestBrowsePlayerContext
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.restdocs.JUnitRestDocumentation
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation
import org.springframework.test.context.junit4.SpringRunner
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultHandlers.print
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder
import org.springframework.test.web.servlet.setup.MockMvcBuilders
import org.springframework.web.context.WebApplicationContext
import rx.Single

@RunWith(SpringRunner::class)
@WebMvcTest(BrowsePlayerController::class, secure = false)
@AutoConfigureRestDocs(outputDir = "target/snippets")
class BrowsePlayerControllerTest {

    @Autowired
    lateinit var mockMvc: MockMvc
    @MockBean
    private lateinit var browsePlayerServiceRepresentable: BrowsePlayerServiceRepresentable
    @MockBean
    private lateinit var standardContext: StandardContext
    @MockBean
    private lateinit var sWDIContext: SWIDContext
    @MockBean
    private lateinit var uIDContext: UIDContext
    @MockBean
    private lateinit var seeAllContext: SeeAllContext
    @MockBean
    private lateinit var apiRequest: ApiRequest
    @Autowired
    lateinit var context: WebApplicationContext
    @MockBean
    private lateinit var transaction: Transaction
    @get:Rule
    var restDocumentation = JUnitRestDocumentation()

    @Before
    fun init() {
        MockitoAnnotations.initMocks(this)
        mockMvc = MockMvcBuilders
                .webAppContextSetup(context)
                .apply<DefaultMockMvcBuilder>(MockMvcRestDocumentation.documentationConfiguration(this.restDocumentation)
                        .uris()
                        .withScheme("http")
                        .withHost("localhost")
                        .withPort(8080))
                .build()
    }

    @Test
    @Throws(Exception::class)
    fun shouldReturnDefaultMessage() {
        val paramsMock = mapOf("swid" to "asudyasd-asdasd-asdasd")
        `when`(apiRequest.parameters).thenReturn(paramsMock)
        val contextRequest = RequestBrowsePlayerContext(this.standardContext, this.sWDIContext, this.uIDContext, this.seeAllContext, apiRequest)
        //`when`(RequestBrowsePlayerContext.(MockMvc., sWDIContext, uIDContext, seeAllContext, apiRequest)).thenReturn(contextRequest)
        `when`(browsePlayerServiceRepresentable.getEntitiesBrowse(contextRequest)).thenReturn(Single.just(presentBrowsePlayers()))
        `when`(browsePlayerServiceRepresentable.getEntitiesBrowse(contextRequest)).thenReturn(Single.just(presentBrowsePlayers()))
        this.mockMvc!!.perform(get("/v1/browse/players/{transaction}{apiRequest}",transaction,apiRequest).param("swid", "asudyasd-asdasd-asdasd")
                .param("uid", "s:20~l:23").param("seeAll", true.toString()).param("lang", "es")
                .param("region", "us").param("version", "23").param("appName", "espn")
                .param("platform", "espn"))
                .andDo(print())
    }

    private fun  presentBrowsePlayers(): BrowsePlayerResponse {
        var sections = arrayListOf<Node>()
        val playersResponse = buildMockSuggestedPlayers()
        val nodePlayers =  Node(null, SectionType.PLAYERS, playersResponse)
        sections.add(nodePlayers)
        val entitiesResponse = buildMockEntitiesBrowse()
        val nodeEntities =  Node(null, SectionType.ENTITIES, entitiesResponse)
        sections.add(nodeEntities)
        return  BrowsePlayerResponse(presentTopHeader(), buildAnalytics(), sections)
    }

    private fun buildMockSuggestedPlayers(): List<SuggestedPlayer> {
        val items = arrayListOf<SuggestedPlayer>()
        items.add(SuggestedPlayer(
                "http://i.espncdn.com/i/players/130x180/45843.jpg",
                "Lionel Messi",
                "SOCCER",
                "dc5f8d51332b0ab2b4b0c97efdc624e0",
                buildAnalyticsPlayer("s:600~t:83", "s:600~l:740", "s:600", SuggestedType.TEAM)
        ))
        items.add(SuggestedPlayer(
                "http://i.espncdn.com/i/players/130x180/22774.jpg",
                "Cristiano Ronaldo",
                "SOCCER",
                "19e162c06bf5d817e9f981bf96001ee2",
                buildAnalyticsPlayer("s:600~t:111", "s:600~l:730", "s:600", SuggestedType.LEAGUE)
        ))
        return items
    }

    private fun  buildAnalyticsPlayer( teamUid:String?,  leagueId :String,  sportUid :String,  suggestedType:SuggestedType):PlayerAnalytics {
        return  PlayerAnalytics(teamUid, leagueId, sportUid, suggestedType)
    }

     private fun presentTopHeader():TopBrowsePlayerHeader {
        val  searchURL = "http://someurl"
        return  TopBrowsePlayerHeader("Player Browse", searchURL)
    }

     private fun buildAnalytics():Analytics {
        return  Analytics(null, null, null, null, null, PageType.ALL_PLAYERS, false)
    }

    private fun buildMockEntitiesBrowse(): List<EntityBrowse> {
        var items = arrayListOf<EntityBrowse>()
        items.add(buildSport("NFL", "s:20~l:28", "http://a.espncdn.com/i/teamlogos/leagues/500/nfl.png"))
        items.add(buildSport("NCAA Football", "s:20~l:23", "http://a.espncdn.com/redesign/assets/img/icons/ESPN-icon-football-college.png"))
        items.add(buildSport("NBA", "s:40~l:46", "http://a.espncdn.com/i/teamlogos/leagues/500/nba.png"))
        items.add(buildSport("NCAA Basketball", "s:40~l:41", "http://a.espncdn.com/redesign/assets/img/icons/ESPN-icon-basketball.png"))
        return items
    }

    private fun buildSport(label: String, uid: String, image: String): EntityBrowse {
        val type = "internalLink"
        val url = "sportscenter://x-callback-url/showPlayerBrowse?uid=$uid"
        val action = BrowsePlayerAction(type, url)
        return  EntityBrowse(label, UID.create(uid), action, image)
    }

I'm not really now how can I send the transaction and apiRequest mocked objects to the controller because I am only calling this.mockMvc!!.perform(get("/v1/browse/players/{transaction}{apiRequest}",transaction,apiRequest) without send any param.

Any ideas?

Aucun commentaire:

Enregistrer un commentaire