Search code examples
unit-testingspring-bootjunitkotlinspring-restcontroller

Rest controller unit testing with spring boot, kotlin and junit


I am currently developping a website with spring boot, kotlin where I am trynig to read Google Trends Rss feeds in xml format and parse them to Json. I want to add unit tests to test my controller but I do not know what to test exactly.

This is my data class:

data class Rss (

    val title: String,
    val source: String,
    val image: String,
    val description: String,
    val url: String
)

This is my rest Controller

@RestController
@RequestMapping(value="/rss")
class RssRestService {

   @GetMapping(value = "/list/item")
   @CrossOrigin("http://localhost:3000")
   fun rss(): List<Rss>? {

         val url = "https://trends.google.fr/trends/hottrends/atom/feed?pn=p1"
         val reader = XmlReader(URL(url))
         val feed: SyndFeed = SyndFeedInput().build(reader)
         return feed.entries.subList(1,6)
                 .map { entry -> Rss(
                 title = entry.title,
                 image = entry.foreignMarkup[1].content[0].value.substring(2),
                 source = entry.foreignMarkup[2].content[0].value,
                 description = entry.foreignMarkup[3].content[1].value.toString(),
                 url = entry.foreignMarkup[3].content[1].value
    ) }

}

And what I did so far for testing is

@RunWith(SpringRunner::class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class DemoApplicationTests {


    @Autowired
    lateinit var testRestTemplate: TestRestTemplate

    @Test
    fun contextLoads() {

    }

    @Test
    fun rssTest() {
        val result = testRestTemplate.getForEntity("/rss/list/item", String::class.java)
        Assert.assertNotNull(result)
        Assert.assertEquals(HttpStatus.OK, result.statusCode)

}

My question is: what should I test? and how to test if the output is write or not?


Solution

  • I splited The controller from the service:

    RestController:

    @RestController
    @RequestMapping(value="/rss")
    
    class RssRestService {
        @Autowired
        lateinit var rssService: RssService
    
    
        @GetMapping(value = "/list/item")
        @CrossOrigin("http://localhost:3000")
    
        fun rss(): List<Rss>? {
    
            val url = "https://trends.google.fr/trends/hottrends/atom/feed?pn=p1"
            return  rssService.getListRss(url)
    
        }
    

    My Service

    @Component
    class RssService{
    
        fun getListRss(url: String): List<Rss> {
            val reader = XmlReader(URL(url))
            val feed: SyndFeed = SyndFeedInput().build(reader)
            return feed.entries.subList(1,6)
                    .map { entry -> Rss(
                            title = entry.title,
                            image = entry.foreignMarkup[1].content[0].value,
                            source = entry.foreignMarkup[2].content[0].value,
                            description = entry.foreignMarkup[3].content[1].value.toString(),
                            url = entry.foreignMarkup[3].content[5].value
                    ) }
        }
    

    And then for testing I created a file with static rss feeds and I passed it's path as a url

    @Test
        fun listItemTest() {
            val result = rssService.getListRss("file:///Home/iroolApp/src/test/kotlin/com/iroolapp/demo/feeds")
            Assert.assertEquals("Iran Nuclear Deal", result[0].title)
            Assert.assertEquals("//t0.gstatic.com/images?q=tbn:ANd9GcTbU16JklJB3H_Ib3dUeu03_4HQPABuE8EthZQRUEG6JMFyDHYytTn-9wexe3E2yYOKO1K9c0Fl", result[0].image)
            Assert.assertEquals("New York Times", result[0].source)
            Assert.assertEquals("Trump Withdraws US From &#39;One-Sided&#39; <b>Iran Nuclear Deal</b>", result[0].description)
            Assert.assertEquals("https://www.nytimes.com/2018/05/08/world/middleeast/trump-iran-nuclear-deal.html", result[0].url)
    
        }
    

    So Is it correct to pass a file with a local path containing the feeds?