Java 如何在Spock中创建通用CRUD控制器测试
甚至可以在Spock中为Spring控制器创建通用单元测试吗?我在Spring Boot中有一个抽象控制器,它由几个特定的控制器扩展。结果是每个控制器都有相同的CRUD实现。所以,现在我想为这些控制器创建类似的单元测试,但我不能在Spock测试中使用构造函数。我犯了一个错误Java 如何在Spock中创建通用CRUD控制器测试,java,unit-testing,spock,Java,Unit Testing,Spock,甚至可以在Spock中为Spring控制器创建通用单元测试吗?我在Spring Boot中有一个抽象控制器,它由几个特定的控制器扩展。结果是每个控制器都有相同的CRUD实现。所以,现在我想为这些控制器创建类似的单元测试,但我不能在Spock测试中使用构造函数。我犯了一个错误 CrudControllerTest.groovy Error:(16, 5) Groovyc: Constructors are not allowed; instead, define a 'setup()' or 's
CrudControllerTest.groovy
Error:(16, 5) Groovyc: Constructors are not allowed; instead, define a 'setup()' or 'setupSpec()' method
IngredientControllerTest.groovy
Error:(7, 5) Groovyc: Constructors are not allowed; instead, define a 'setup()' or 'setupSpec()' method
对于belowe代码
abstract class CrudControllerTest<T, R extends JpaRepository<T, Long>, C extends CrudController<T,R>> extends Specification {
private String endpoint
private def repository
private def controller
private MockMvc mockMvc
CrudControllerTest(def endpoint, R repository, C controller) {
this.endpoint = endpoint
this.repository = repository
this.controller = controller
this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build()
}
def "Should get 404 when product does not exists"() {
given:
repository.findById(1) >> Optional.empty()
when:
def response = mockMvc.perform(MockMvcRequestBuilders.get(endpoint + '/1')).andReturn().response
then:
response.status == HttpStatus.NOT_FOUND.value()
}
}
class IngredientControllerTest extends CrudControllerTest<Ingredient, IngredientRepository, IngredientController> {
IngredientControllerTest() {
def repository = Mock(IngredientRepository)
super("/ingredients", repository, new IngredientController(Mock(repository)))
}
}
抽象类CrudControllerTest扩展了规范{
私有字符串端点
专用def存储库
专用def控制器
私有MockMvc MockMvc
CrudControllerTest(def端点、R存储库、C控制器){
this.endpoint=endpoint
this.repository=存储库
this.controller=控制器
this.mockMvc=MockMvcBuilders.standaloneSetup(controller.build())
}
def“当产品不存在时应获得404”(){
鉴于:
repository.findById(1)>>可选的.empty()
什么时候:
def response=mockMvc.perform(MockMvcRequestBuilders.get(endpoint+'/1')).andReturn().response
然后:
response.status==HttpStatus.NOT_FOUND.value()
}
}
类IngCreditControllerTest扩展了CrudControllerTest{
IngCreditControllerTest(){
def存储库=模拟(IngredEntrepository)
超级(“/Components”,存储库,新的IngredientController(模拟(存储库)))
}
}
在Spock中实现通用单元测试还有其他方法吗?您不能为
规范使用构造函数,而可以使用模板方法模式。使用单独的方法:
abstract class CrudControllerTest extends Specification {
private String endpoint
private def repository
private def controller
private MockMvc mockMvc
def setup() {
endpoint = createEndpoint()
repository = createRepository()
controller = createController()
mockMvc = MockMvcBuilders.standaloneSetup(controller).build()
}
abstract createEndpoint()
abstract createRepository()
abstract createController()
def "Should get 404 when product does not exists"() {
given:
repository.findById(1) >> Optional.empty()
when:
def response = mockMvc.perform(MockMvcRequestBuilders.get(endpoint + '/1')).andReturn().response
then:
response.status == HttpStatus.NOT_FOUND.value()
}
}
class IngredientControllerTest extends CrudControllerTest<Ingredient, IngredientRepository, IngredientController> {
def createEndpoint() {
"/ingredients"
}
def createRepository {
Mock(IngredientRepository)
}
def createController() {
new IngredientController(repository)
}
}
抽象类CrudControllerTest扩展了规范{
私有字符串端点
专用def存储库
专用def控制器
私有MockMvc MockMvc
def设置(){
端点=createEndpoint()
repository=createRepository()
controller=createController()
mockMvc=MockMvcBuilders.standaloneSetup(controller.build())
}
抽象createEndpoint()
抽象createRepository()
抽象createController()
def“当产品不存在时应获得404”(){
鉴于:
repository.findById(1)>>可选的.empty()
什么时候:
def response=mockMvc.perform(MockMvcRequestBuilders.get(endpoint+'/1')).andReturn().response
然后:
response.status==HttpStatus.NOT_FOUND.value()
}
}
类IngCreditControllerTest扩展了CrudControllerTest{
def createEndpoint(){
“/成分”
}
def createRepository{
模拟(IngredEntrepository)
}
def createController(){
新IngreditController(存储库)
}
}
或者使用返回所有内容的方法,这有点好,因为您的一些值需要引用其他值:
abstract class CrudControllerTest extends Specification {
private String endpoint
private def repository
private def controller
private MockMvc mockMvc
def setup() {
(endpoint, repository, controller) = createSut()
mockMvc = MockMvcBuilders.standaloneSetup(controller).build()
}
abstract createSut()
def "Should get 404 when product does not exists"() {
given:
repository.findById(1) >> Optional.empty()
when:
def response = mockMvc.perform(MockMvcRequestBuilders.get(endpoint + '/1')).andReturn().response
then:
response.status == HttpStatus.NOT_FOUND.value()
}
}
class IngredientControllerTest extends CrudControllerTest<Ingredient, IngredientRepository, IngredientController> {
def createSut() {
def repo = Mock(IngredientRepository)
["/ingredients", repo, new IngredientController(repository)]
}
}
抽象类CrudControllerTest扩展了规范{
私有字符串端点
专用def存储库
专用def控制器
私有MockMvc MockMvc
def设置(){
(端点、存储库、控制器)=createSut()
mockMvc=MockMvcBuilders.standaloneSetup(controller.build())
}
抽象createSut()
def“当产品不存在时应获得404”(){
鉴于:
repository.findById(1)>>可选的.empty()
什么时候:
def response=mockMvc.perform(MockMvcRequestBuilders.get(endpoint+'/1')).andReturn().response
然后:
response.status==HttpStatus.NOT_FOUND.value()
}
}
类IngCreditControllerTest扩展了CrudControllerTest{
def createSut(){
def回购=模拟(IngredIndepository)
[“/Components”,回购,新IngreditController(存储库)]
}
}
您不能将构造函数用于规范
,相反,您可以使用模板方法模式。使用单独的方法:
abstract class CrudControllerTest extends Specification {
private String endpoint
private def repository
private def controller
private MockMvc mockMvc
def setup() {
endpoint = createEndpoint()
repository = createRepository()
controller = createController()
mockMvc = MockMvcBuilders.standaloneSetup(controller).build()
}
abstract createEndpoint()
abstract createRepository()
abstract createController()
def "Should get 404 when product does not exists"() {
given:
repository.findById(1) >> Optional.empty()
when:
def response = mockMvc.perform(MockMvcRequestBuilders.get(endpoint + '/1')).andReturn().response
then:
response.status == HttpStatus.NOT_FOUND.value()
}
}
class IngredientControllerTest extends CrudControllerTest<Ingredient, IngredientRepository, IngredientController> {
def createEndpoint() {
"/ingredients"
}
def createRepository {
Mock(IngredientRepository)
}
def createController() {
new IngredientController(repository)
}
}
抽象类CrudControllerTest扩展了规范{
私有字符串端点
专用def存储库
专用def控制器
私有MockMvc MockMvc
def设置(){
端点=createEndpoint()
repository=createRepository()
controller=createController()
mockMvc=MockMvcBuilders.standaloneSetup(controller.build())
}
抽象createEndpoint()
抽象createRepository()
抽象createController()
def“当产品不存在时应获得404”(){
鉴于:
repository.findById(1)>>可选的.empty()
什么时候:
def response=mockMvc.perform(MockMvcRequestBuilders.get(endpoint+'/1')).andReturn().response
然后:
response.status==HttpStatus.NOT_FOUND.value()
}
}
类IngCreditControllerTest扩展了CrudControllerTest{
def createEndpoint(){
“/成分”
}
def createRepository{
模拟(IngredEntrepository)
}
def createController(){
新IngreditController(存储库)
}
}
或者使用返回所有内容的方法,这有点好,因为您的一些值需要引用其他值:
abstract class CrudControllerTest extends Specification {
private String endpoint
private def repository
private def controller
private MockMvc mockMvc
def setup() {
(endpoint, repository, controller) = createSut()
mockMvc = MockMvcBuilders.standaloneSetup(controller).build()
}
abstract createSut()
def "Should get 404 when product does not exists"() {
given:
repository.findById(1) >> Optional.empty()
when:
def response = mockMvc.perform(MockMvcRequestBuilders.get(endpoint + '/1')).andReturn().response
then:
response.status == HttpStatus.NOT_FOUND.value()
}
}
class IngredientControllerTest extends CrudControllerTest<Ingredient, IngredientRepository, IngredientController> {
def createSut() {
def repo = Mock(IngredientRepository)
["/ingredients", repo, new IngredientController(repository)]
}
}
抽象类CrudControllerTest扩展了规范{
私有字符串端点
专用def存储库
专用def控制器
私有MockMvc MockMvc
def设置(){
(端点、存储库、控制器)=createSut()
mockMvc=MockMvcBuilders.standaloneSetup(controller.build())
}
抽象createSut()
def“当产品不存在时应获得404”(){
鉴于:
repository.findById(1)>>可选的.empty()
什么时候:
def response=mockMvc.perform(MockMvcRequestBuilders.get(endpoint+'/1')).andReturn().response
然后:
response.status==HttpStatus.NOT_FOUND.value()
}
}
类IngCreditControllerTest扩展了CrudControllerTest{
def createSut(){
def回购=模拟(IngredIndepository)
[“/成分”,回购协议,