unit-testing - 如何对使用springSecurityService的 Controller 进行单元测试?

标签 unit-testing grails mocking spring-security

我有一个这样的用户类:

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/

    相关文章:

    unit-testing - 每晚构建与持续集成 : Long-Running Automated Tests

    java - 单元测试是否已捕获并处理异常

    tomcat - 部署错误无法创建类 [SearchableGrailsPlugin] 的新实例!

    hibernate - 在Grails应用程序中使用奇怪的 hibernate/Gorm行为

    c# - 如何在 C# 中模拟基类属性或方法

    javascript - 如何修复 TypeError 不是一个函数(用 Jest 测试 promises)

    java - 延迟抛出的异常以添加软断言

    unit-testing - Grails 2.0:POST和flash.message

    unit-testing - 关于与其他方法组合的stubbing方法的问题

    javascript - 内存中 Web Api 返回 {data : Array[0]}