Spock 单元测试使用 spring 数据导致可选错误
Spock unit test using spring data causing errors in Optional
我开始在 Spring 引导 + Spring 数据项目中使用 Spock 框架执行测试。
当我尝试模拟我的存储库时出现问题,但特别是在某些方法中 return 是可选的。
Cannot invoke method orElse() on null object
java.lang.NullPointerException: Cannot invoke method orElse() on null object
at br.com.moskit.jivochat.service.UserService.getResponsible(UserService.groovy:37)
at br.com.moskit.jivochat.service.UserServiceTest.Retrive the responsible of interaction in JivoChat by configs of plugin item(UserServiceTest.groovy:65)
我的测试实现:
class UserServiceTest extends Specification {
UserService userService
void setup() {
userService = new UserService()
userService.userRepository = Mock(UserRepository)
GroovyMock(Optional)
}
def "Retrive the responsible of interaction in JivoChat by configs of plugin item"() {
given: 'that exist a collection of JivoChat interaction configurations'
List<Map> agents = null
Map configs = [responsibleId: 1]
userService.userRepository.findById(_) >> Optional.of(new User(username: "XPTO")).orElse("null")
when: 'the main method is called'
User user = userService.getResponsible(configs, agents)
then: 'the method get last agent and search in DB by e-mail'
1 * userService.userRepository.findById(_)
}
}
我的方法:
User getResponsible(Map configs, List<Map> agents) {
//Ommited...
Integer responsibleId = configs.responsibleId as Integer
Optional<User> userOptional = userRepository.findById(responsibleId)
User user = userOptional.orElse(null)
user
}
这是经典的,答案可以在Spock manual chapter "Combining Mocking and Stubbing"中找到:
NOTE: Mocking and stubbing of the same method call has to happen in the same interaction.
所以解决方案如下所示:
package de.scrum_master.Whosebug.q66208875
class User {
int id
String username
}
package de.scrum_master.Whosebug.q66208875
class UserRepository {
Optional<User> findById(int id) {
Optional.of(new User(id: id, username: "User #$id"))
}
}
package de.scrum_master.Whosebug.q66208875
class UserService {
UserRepository userRepository = new UserRepository()
User getResponsible(Map configs, List<Map> agents) {
Integer responsibleId = configs.responsibleId as Integer
Optional<User> userOptional = userRepository.findById(responsibleId)
User user = userOptional.orElse(null)
user
}
}
package de.scrum_master.Whosebug.q66208875
import spock.lang.Specification
class UserServiceTest extends Specification {
UserService userService
void setup() {
userService = new UserService()
userService.userRepository = Mock(UserRepository)
}
def "retrieve the responsible of interaction in JivoChat by configs of plugin item"() {
given: 'that exist a collection of JivoChat interaction configurations'
List<Map> agents = null
Map configs = [responsibleId: 1]
when: 'the main method is called'
User user = userService.getResponsible(configs, agents)
then: 'the method get last agent and search in DB by e-mail'
1 * userService.userRepository.findById(_) >> Optional.of(new User(username: "XPTO"))//.orElse("null")
}
}
看看我是如何在一行中结合存根方法结果和验证模拟交互的?
您也不需要任何 GroovyMock(Optional)
,无论它的用途是什么。您还希望确保获得正确的 findById(_)
结果类型并删除错误的 .orElse("null")
.
我开始在 Spring 引导 + Spring 数据项目中使用 Spock 框架执行测试。
当我尝试模拟我的存储库时出现问题,但特别是在某些方法中 return 是可选的。
Cannot invoke method orElse() on null object
java.lang.NullPointerException: Cannot invoke method orElse() on null object
at br.com.moskit.jivochat.service.UserService.getResponsible(UserService.groovy:37)
at br.com.moskit.jivochat.service.UserServiceTest.Retrive the responsible of interaction in JivoChat by configs of plugin item(UserServiceTest.groovy:65)
我的测试实现:
class UserServiceTest extends Specification {
UserService userService
void setup() {
userService = new UserService()
userService.userRepository = Mock(UserRepository)
GroovyMock(Optional)
}
def "Retrive the responsible of interaction in JivoChat by configs of plugin item"() {
given: 'that exist a collection of JivoChat interaction configurations'
List<Map> agents = null
Map configs = [responsibleId: 1]
userService.userRepository.findById(_) >> Optional.of(new User(username: "XPTO")).orElse("null")
when: 'the main method is called'
User user = userService.getResponsible(configs, agents)
then: 'the method get last agent and search in DB by e-mail'
1 * userService.userRepository.findById(_)
}
}
我的方法:
User getResponsible(Map configs, List<Map> agents) {
//Ommited...
Integer responsibleId = configs.responsibleId as Integer
Optional<User> userOptional = userRepository.findById(responsibleId)
User user = userOptional.orElse(null)
user
}
这是经典的,答案可以在Spock manual chapter "Combining Mocking and Stubbing"中找到:
NOTE: Mocking and stubbing of the same method call has to happen in the same interaction.
所以解决方案如下所示:
package de.scrum_master.Whosebug.q66208875
class User {
int id
String username
}
package de.scrum_master.Whosebug.q66208875
class UserRepository {
Optional<User> findById(int id) {
Optional.of(new User(id: id, username: "User #$id"))
}
}
package de.scrum_master.Whosebug.q66208875
class UserService {
UserRepository userRepository = new UserRepository()
User getResponsible(Map configs, List<Map> agents) {
Integer responsibleId = configs.responsibleId as Integer
Optional<User> userOptional = userRepository.findById(responsibleId)
User user = userOptional.orElse(null)
user
}
}
package de.scrum_master.Whosebug.q66208875
import spock.lang.Specification
class UserServiceTest extends Specification {
UserService userService
void setup() {
userService = new UserService()
userService.userRepository = Mock(UserRepository)
}
def "retrieve the responsible of interaction in JivoChat by configs of plugin item"() {
given: 'that exist a collection of JivoChat interaction configurations'
List<Map> agents = null
Map configs = [responsibleId: 1]
when: 'the main method is called'
User user = userService.getResponsible(configs, agents)
then: 'the method get last agent and search in DB by e-mail'
1 * userService.userRepository.findById(_) >> Optional.of(new User(username: "XPTO"))//.orElse("null")
}
}
看看我是如何在一行中结合存根方法结果和验证模拟交互的?
您也不需要任何 GroovyMock(Optional)
,无论它的用途是什么。您还希望确保获得正确的 findById(_)
结果类型并删除错误的 .orElse("null")
.