如何在Grails单元测试中使用自定义编解码器

Ben*_*est 5 grails

我正在使用InfoQ的Grails教程,名为Grails入门,第二版,我正在尝试将自定义编解码器添加到单元测试中.我的环境是Grails 1.3.7和Groovy 1.7.8.

所以编解码器是SHACodec.groovy,它存在于grails-app/utils中.内容如下:

import java.security.MessageDigest 

class SHACodec{ 
  static encode = {target-> 
    MessageDigest md = MessageDigest.getInstance('SHA') 
    md.update(target.getBytes('UTF-8')) 
    return new String(md.digest()).encodeAsBase64()     
  }     
} 
Run Code Online (Sandbox Code Playgroud)

当我登录应用程序时,编解码器工作得很好.它被用于我的UserController.authenticate()中的密码字段

def authenticate = { 
    def user =  
          User.findByLoginAndPassword(params.login, params.password.encodeAsSHA()) 
        if(user){ 
      session.user = user 
          flash.message = "Hello ${user.login}!" 
      redirect(controller:"race", action:"list")       
        }else{ 
      flash.message = "Sorry, ${params.login}. Please try again." 
          redirect(action:"login") 
    }         
    }
Run Code Online (Sandbox Code Playgroud)

当我将其添加到单元测试时,会显示以下错误:

没有这样的属性:类的SHACodec:racetrack.UserControllerTests groovy.lang.MissingPropertyException:没有这样的属性:类的SHACodec:racetrack的Runtrack.UserControllerTests.UserControllerTests.testAuthenticate(UserControllerTests.groovy:39)

测试是:

package racetrack

import org.codehaus.groovy.grails.plugins.codecs.*
import grails.test.*

class UserControllerTests extends ControllerUnitTestCase {
    protected void setUp() {
        super.setUp()

        String.metaClass.encodeAsSHA = {->  
          SHACodec.encode(delegate) 
        }
    }

    protected void tearDown() {
        super.tearDown()
    }

void testAuthenticate(){ 

  def jdoe = new User(login:"jdoe", password:"password".encodeAsSHA()) 
  mockDomain(User, [jdoe]) 

  controller.params.login = "jdoe" 
  controller.params.password = "password" 
  controller.authenticate() 
  assertNotNull controller.session.user 
  assertEquals "jdoe", controller.session.user.login 

  controller.params.password = "foo" 
  controller.authenticate() 
  assertTrue controller.flash.message.startsWith( 
    "Sorry, jdoe")       
}
Run Code Online (Sandbox Code Playgroud)

到目前为止我找到了两个不同的建议 首先,直接从测试中调用编解码器:

SHACodec codec = new SHACodec()
codec.encode("password")
Run Code Online (Sandbox Code Playgroud)

其次,使用集成测试而不是单元测试.

每个选项的结果都相同.我错过了什么小事?

在此先感谢您的时间!

hvg*_*des 2

您没有导入您的编解码器——您正在导入默认的 grails 编解码器。您只需使测试中编解码器的导入与编解码器所在的确切包路径匹配即可。如果您使用的是 IDE,请让它尝试为您导入编解码器...