Mat*_*t L 9 grails unit-testing mocking spring-security
我有这样的用户类:
class User {
transient springSecurityService
String displayName
String password
<snip>
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
Run Code Online (Sandbox Code Playgroud)
还有一个UserController.我正在尝试编写单元测试UserController但是我收到此错误用于保存,更新和删除测试:
java.lang.NullPointerException: Cannot invoke method encodePassword() on null object
Run Code Online (Sandbox Code Playgroud)
我有什么方法可以通过嘲讽来实现这一点?
我已经尝试了许多模拟代码的组合,如下所示,但我不知所措.
defineBeans {
springSecurityService(SpringSecurityService)
}
Run Code Online (Sandbox Code Playgroud)
任何建议将不胜感激.
我个人不喜欢在生产代码中添加逻辑来帮助满足测试要求.有时你必须决定什么是最好的.几个选项......
如果这个代码(或遇到相同问题的代码)散布在整个应用程序中,那么你可能想要找出一种方法来模拟所有测试用例的单元测试中的这些调用,这样你就不会重复设置到处努力.模拟这个的简单方法是使用metaClassing.
@Test
public void something() {
def user = ...
def springSecurityService = new Object()
springSecurityService.metaClass.encodePassword = {String password -> "ENCODED_PASSWORD"}
user.springSecurityService = springSecurityService
...
}
Run Code Online (Sandbox Code Playgroud)
现在,当springSecurityService.encodePassword调用gets 时,它应该返回"ENCODED_PASSWORD".我也创建了一个Object而不是实例化一个新的,SpringSecurityService因为如果你实例化一个实际的服务,那么你最终可能会意外地在不知不觉中调用该服务上的实际方法,并且你的测试通过了错误的原因.我宁愿得到一个没有这样的方法错误,而不是通过不应该通过的测试.
我是这样做的:
protected void encodePassword() {
// SpringSecutiryService is not injected in tests.
if (springSecurityService)
password = springSecurityService.encodePassword(formPassword)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3749 次 |
| 最近记录: |