Spring BootとCortlinを使用したブログWebの作成(3)

14018 ワード

ムースタッチテンプレートの修正

src/main/resources/templates/blog.mustache
{{> header}}

<h1>{{title}}</h1>

<div class="articles">
    {{#articles}}
        <section>
            <header class="article-header">
                <h2 class="article-title"><a href="/article/{{slug}}">{{title}}</a></h2>
                <div class="article-meta">By <strong>{{author.firstName}}</strong>, on <strong>{{addedAt}}</strong></div>
            </header>
            <div class="article-description">
                {{headline}}
            </div>
        </section>
    {{/articles}}
</div>

{{> footer}}
新規テンプレートarticleの追加src/main/resources/templates/article.mustache
{{> header}}

<section class="article">
    <header class="article-header">
        <h1 class="article-title">{{article.title}}</h1>
        <p class="article-meta">By  <strong>{{article.author.firstName}}</strong>, on <strong>{{article.addedAt}}</strong></p>
    </header>
    <div class="article-description">
        {{article.headline}}
        {{article.content}}
    </div>
</section>

{{> footer}}
その後、Html Controllerを更新します.src/main/kotlin/com/example/demo/HtmlController.kt
package com.example.demo

import com.example.demo.blog.Article
import com.example.demo.blog.ArticleRepositoriy
import com.example.demo.blog.User
import com.example.demo.blog.format
import org.springframework.http.HttpStatus
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.ui.set
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.server.ResponseStatusException

@Controller
class HtmlController (private val repository: ArticleRepositoriy) {

    @GetMapping("/")
    fun blog(model: Model): String {
        model["title"] = "Blog"
        model["articles"] = repository.findAllByOrderByAddedAtDesc().map {
            it.render()
        }
        return "blog"
    }

    @GetMapping("/article/{slug}")
    fun article(@PathVariable slug: String, model: Model): String{
        val article = repository
            .findBySlug(slug)
            ?. run{ this.render() }
            ?:throw ResponseStatusException(HttpStatus.NOT_FOUND, "This article does not exist")
        model["title"] = article.title
        model["article"] = article
        return "article"
    }

    fun Article.render() = RenderArticle(
        slug,
        title,
        headline,
        content,
        author,
        addedAt.format()
    )

    data class RenderArticle(
        val slug: String,
        val title: String,
        val headline: String,
        val content: String,
        val author: User,
        val addedAt: String
    )
}
Autowiredを自動的に適用するので@autowiredを使用する必要はありません
データをデータベースに入れるsrc/main/kotlin/com/example/demo/BlogConfiguration.kt
package com.example.demo.blog

import org.springframework.boot.ApplicationRunner
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class BlogConfiguration {

    @Bean
    fun databaseInitializer(userRepository: UserRepository,
                            articleRepository: ArticleRepositoriy) =
        ApplicationRunner{
            val user = userRepository.save(User("login", "firstName", "lastName"))
            articleRepository.save(Article("title1", "headline1", "content1", user))
            articleRepository.save(Article("title2", "headline2", "content2", user))
        }
}
最後に、テストコードを作成して実行し、正常に動作しているかどうかを確認します.src/test/kotlin/com/example/blog/IntegrationTests.kt
package com.example.demo

import com.example.demo.blog.toSlug
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.BeforeAll
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.web.client.TestRestTemplate
import org.springframework.boot.test.web.client.getForEntity
import org.springframework.http.HttpStatus

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class IntegrationTests(@Autowired val restTemplate: TestRestTemplate){
    @BeforeAll
    fun setup(){
        println(">> Setup")
    }

    @Test
    fun `Assert blog page title, content and status code`() {
        println(" >> Assert blog page test, content and status code")
        val entity = restTemplate.getForEntity<String>("/")
        assertThat(entity.statusCode).isEqualTo(HttpStatus.OK)
        assertThat(entity.body).contains("<h1>Blog</h1>")
    }

    @Test
    fun `Assert article page title, content and status code`() {
        println(">> Assert article page title, content and status code")
        val title = "title1"
        val entity = restTemplate.getForEntity<String>("/article/${title.toSlug()}")
        assertThat(entity.statusCode).isEqualTo(HttpStatus.OK)
        assertThat(entity.body).contains(title, "headline", "content")
    }

    @AfterAll
    fun teardown(){
        println(">> Tear down")
    }
}
テストコードが成功すると、http://localhost:8080/活動場所を表すで正常なブログが表示されます.


JPAでデータを検索したり、MustachテンプレートエンジンでWebページを作成したり、統合テストを行ったりしました

Reference


https://spring.io/guides/tutorials/spring-boot-kotlin/