简体   繁体   English

在spring-boot + kotlin + Junit中进行单元测试POST API

[英]Unit test POST API in spring-boot + kotlin + Junit

I'm pretty new to spring boot and kotlin. 我对Spring Boot和Kotlin很陌生。 I've started with one basic app from net and writing unit test, but I'm getting following error: 我已经从网络上的一个基本应用程序开始并编写了单元测试,但出现以下错误:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: articleRepository.save(article) must not be null

Let me show you the code: Entity Class 让我向您展示代码:实体类

@Entity
data class Article (
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long = 0,

    @get: NotBlank
    val title: String = "",

    @get: NotBlank
    val content: String = ""
)

controller: 控制器:

@PostMapping("/articles")
fun createNewArticle(@Valid @RequestBody article: Article) : Article {
    return articleRepository.save(article)
}

Repository: 库:

@Repository
interface ArticleRepository : JpaRepository<Article, Long>

Test File: 测试文件:

RunWith(SpringRunner::class)
@SpringBootTest
class KotlinDemoApplicationTests {

lateinit var mvc: MockMvc

@InjectMocks
lateinit var controller: ArticleController

@Mock
lateinit var respository: ArticleRepository

@Before
fun setup() {
    MockitoAnnotations.initMocks(this)
    mvc = MockMvcBuilders.standaloneSetup(controller).setMessageConverters(MappingJackson2HttpMessageConverter()).build()
}

@Test
fun createBlog() {
    var article = Article(1, "Test", "Test Content")
    var jsonData = jacksonObjectMapper().writeValueAsString(article)
    mvc.perform(MockMvcRequestBuilders.post("/api/articles/").contentType(MediaType.APPLICATION_JSON).content(jsonData))
            .andExpect(MockMvcResultMatchers.status().isOk)
            .andDo(MockMvcResultHandlers.print())
            .andReturn()
}
}

When I'm running this test file, getting error mentioned above. 当我运行此测试文件时,出现上述错误。 Please help me with this. 请帮我解决一下这个。

The problem is your ArticleRepository mock. 问题是您的ArticleRepository模拟。

While you correctly inject it into your Controller, you're not specifiying what a call to save should return. 当您将其正确注入Controller时,您并未指定save调用save返回什么。 It therefore returns null , which is not allowed in Kotin because you specified it as non-optional. 因此,它返回null ,这在Kotin中是不允许的,因为您将其指定为非可选。

Either you allow your controller's createNewArticle to return null , by adding a ? 您可以通过添加?来允许控制器的createNewArticle返回null ? , that is changing its signature to ,即将其签名更改为

fun createNewArticle(@Valid @RequestBody article: Article) : Article? {...}

Or you set-up the mock so that it does not return null , but an article. 或者,您可以设置该模拟,以便它不会返回null ,而是返回一个文章。

@Before
fun setup() {
    MockitoAnnotations.initMocks(this)
    ...
    `when`(respository.save(any())
        .thenReturn(Article()) // creates a new article
}

(Alternatively, there's also Mockito's returnsFirstArg() in case you don't want to invoke the construtor.) (或者,如果您不想调用构造函数 ,还可以使用Mockito的returnsFirstArg() 。)


Note that using any() in this case will only work if you're using mockito-kotlin 请注意,在这种情况下使用any()仅在您使用嘲笑kotlin时才有效
If you don't want to use it, check this answer 如果您不想使用它,请检查此答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM