我有一个这样的用户类:
class User {
transient springSecurityService
String displayName
String password
<snip>
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
还有一个
UserController
。我正在尝试为
UserController
编写单元测试,但是在保存,更新和删除测试时遇到此错误:java.lang.NullPointerException: Cannot invoke method encodePassword() on null object
要使此功能正常工作,我必须设置什么模拟方式?
我已经尝试了许多模拟代码的组合,例如以下示例,但是我很茫然。
defineBeans {
springSecurityService(SpringSecurityService)
}
任何建议将不胜感激。
最佳答案
我个人不喜欢在生产代码中添加逻辑以帮助满足测试。有时,您必须决定最好的做法。几个选择...
如果此代码(或遇到相同问题的代码)散布在整个应用程序中,则您可能想找出一种在所有测试用例的单元测试中模拟这些调用的方法,从而避免重复设置处处努力。一个简单的模拟方法是使用metaClassing。
@Test
public void something() {
def user = ...
def springSecurityService = new Object()
springSecurityService.metaClass.encodePassword = {String password -> "ENCODED_PASSWORD"}
user.springSecurityService = springSecurityService
...
}
现在,当
springSecurityService.encodePassword
被调用时,它应该返回“ENCODED_PASSWORD”。我还创建了一个Object
而不是实例化一个新的SpringSecurityService
,因为如果实例化一个实际的服务,那么您可能最终会意外地,不知不觉地对该服务调用实际的方法,并且由于错误的原因而使测试通过。我宁愿得到一个没有这样的方法错误,也不应该通过不应该通过的测试。
关于unit-testing - 如何对使用springSecurityService的 Controller 进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8516837/