2011-03-11 68 views
5

我正在通过一个名为Grails第二版入门的InfoQ Grails教程开展工作,并试图将自定义编解码器添加到单元测试中。我的环境是Grails 1.3.7和Groovy 1.7.8。如何在Grails单元测试中使用自定义编解码器

所以编解码器是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()  
    }  
} 

编解码器工作得很好。它被用于密码字段在我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") 
    }   
    } 

当我加入这一个单元测试,显示以下错误:

没有这样的属性:SHACodec类: racetrack.UserControllerTests groovy.lang.MissingPropertyException: 没有这样的属性:SHACodec类: racetrack.UserControllerTests在 racetrack.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")  
} 

我发现了两个不同的建议为止。 首先,直接从测试调用编解码器:

SHACodec codec = new SHACodec() 
codec.encode("password") 

其次,使用一个集成测试,而不是一个单元测试的。

结果对每个选项都是一样的。我错过了什么小事?

预先感谢您的时间!

回答

2

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

+0

Thanks hvgotcodes。那么我会在grails-app/utils下创建一个跑道目录,并在编解码器的开头添加“package racetrack”?我还没有安装IDE,只是暂时使用文本编辑器。 – BenjaminDWest 2011-03-11 15:51:07

+1

@benjamindwest,是的,你将不得不手动创建包结构。所以在预先存在的grails-app/utils下有类似com/racetrack/security/codecs的东西。然后这个包是com.racetrack.security.codecs,你会导入com.racetrack.security.codecs.SHACodec – hvgotcodes 2011-03-11 16:11:44

+0

非常感谢。这解决了我的问题。 – BenjaminDWest 2011-04-28 11:24:04

1

使用GrailsUnitTestCase的loadCodec方法。这很简单。参见下文的例子:

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

class SomeTests extends GrailsUnitTestCase { 
    protected void setUp() { 
     super.setUp() 
     loadCodec(HTMLCodec) 
    } 

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

    void testSomething() { 
     assertEquals "&lt;p&gt;Hello World&lt;/p&gt;", "<p>Hello World</p>".encodeAsHTML() 
    } 
} 
0

从@hvgotcodes的答案是正确的,但你也需要进口作品前,在grails-app/utils的文件夹添加到您的Java构建路径(至少这是我需要什么用SpringSource Eclipse IDE做)。

相关问题