在这两种情况下,您都在使用EmbeddedServer
实现 - NettyHttpServer
。这是一个代表 Micronaut 服务器实现的抽象(NettyHttpServer
在本例中为 a)。
主要区别在于micronaut-test
提供了组件和注释,使编写 Micronaut HTTP 单元测试更加简单。之前micronaut-test
,您必须手动启动应用程序:
EmbeddedServer server = ApplicationContext.run(EmbeddedServer)
然后你必须准备一个 HTTP 客户端,例如:
HttpClient http = HttpClient.create(server.URL)
将其micronaut-test
简化为在测试类上添加@MicronautTest
注释,运行程序启动嵌入式服务器并初始化您可以注入的所有 bean。就像您RxHttpClient
在示例中进行注入一样。
值得一提的第二件事是@MicronautTest
注解还允许您使用@MockBean
注解来覆盖现有的 bean,其中包含一些您可以在测试级别定义的模拟。默认情况下,@MicronautTest
不模拟任何 bean,因此启动的应用程序反映 1:1 应用程序的运行时环境。当您EmbeddedServer
手动启动时也会发生同样的事情 - 这只是启动常规 Micronaut 应用程序的一种编程方式。
所以结论很简单——如果你想在你的测试类中编写更少的样板代码,使用micronaut-test
它的所有注释来使你的测试更简单。没有它,您将不得不手动控制所有事情(启动 Micronaut 应用程序,从应用程序上下文中检索 bean 而不是使用@Inject
注释,等等。)
最后但并非最不重要的一点是,这里是没有编写的相同测试micronaut-test
:
package com.github.wololock.micronaut.products
import io.micronaut.context.ApplicationContext
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpStatus
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.RxHttpClient
import io.micronaut.http.client.exceptions.HttpClientResponseException
import io.micronaut.runtime.server.EmbeddedServer
import spock.lang.AutoCleanup
import spock.lang.Shared
import spock.lang.Specification
class ProductControllerSpec extends Specification {
@Shared
@AutoCleanup
EmbeddedServer server = ApplicationContext.run(EmbeddedServer)
@Shared
@AutoCleanup
HttpClient http = server.applicationContext.createBean(RxHttpClient, server.URL)
def "should return PROD-001"() {
when:
Product product = http.toBlocking().retrieve(HttpRequest.GET("/product/PROD-001"), Product)
then:
product.id == 'PROD-001'
and:
product.name == 'Micronaut in Action'
and:
product.price == 29.99
}
def "should support 404 response"() {
when:
http.toBlocking().exchange(HttpRequest.GET("/product/PROD-009"))
then:
def e = thrown HttpClientResponseException
e.status == HttpStatus.NOT_FOUND
}
}
在这种情况下,我们不能使用@Inject
注解,创建/注入 bean 的唯一方法是applicationContext
直接使用对象。(请记住,在这种情况下,RxHttpClient
bean 不存在于上下文中,我们必须创建它 -micronaut-test
以防这个 bean 预先为我们准备好。)
这是micronaut-test
使测试更简单的相同测试:
package com.github.wololock.micronaut.products
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpStatus
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.annotation.Client
import io.micronaut.http.client.exceptions.HttpClientResponseException
import io.micronaut.test.annotation.MicronautTest
import spock.lang.Specification
import javax.inject.Inject
@MicronautTest
class ProductControllerSpec extends Specification {
@Inject
@Client("/")
HttpClient http
def "should return PROD-001"() {
when:
Product product = http.toBlocking().retrieve(HttpRequest.GET("/product/PROD-001"), Product)
then:
product.id == 'PROD-001'
and:
product.name == 'Micronaut in Action'
and:
product.price == 29.99
}
def "should support 404 response"() {
when:
http.toBlocking().exchange(HttpRequest.GET("/product/PROD-009"))
then:
def e = thrown HttpClientResponseException
e.status == HttpStatus.NOT_FOUND
}
}
样板代码更少,效果相同。我们可以即使@Inject EmbeddedServer embeddedServer
想访问它,但没有必要这样做。