您如何在 grails 2.3 中测试服务或控制器方法

Posted

技术标签:

【中文标题】您如何在 grails 2.3 中测试服务或控制器方法【英文标题】:How do you test service or controller methods in grails 2.3 【发布时间】:2013-09-30 17:10:57 【问题描述】:

我刚开始使用 grails 2.3,但在运行单元测试时遇到了问题。到目前为止我所做的是我已经运行了

grails create-app new-app
grails create-service NewService
grails test-app

这会产生

| Running 1 unit test...
| Completed 0 unit test, 0 failed in 0m 2s
| Tests PASSED - view reports in C:\Git\aspera_web\target\test-reports

到目前为止一切顺利,但如果我编辑方法

void "test something"() 

在 NewServiceSpec 类中

void "test something"() 
    assert false

再次运行我又得到了

| Running 1 unit test...
| Completed 0 unit test, 0 failed in 0m 2s
| Tests PASSED - view reports in C:\Git\aspera_web\target\test-reports

然后我查看了 spock 文档并尝试再次编辑我的测试。这次来

void "test something"() 
    expect: 1 == 2

产生

| Running 1 unit test...
| Running 1 unit test... 1 of 1
| Failure:  test something(aspera_web.NewServiceSpec)
|  Condition not satisfied:
false
        at aspera_web.NewServiceSpec.test something(NewServiceSpec.groovy:19)
| Completed 1 unit test, 1 failed in 0m 2s
| Tests FAILED  - view reports in C:\Git\aspera_web\target\test-reports

这看起来很有希望,所以下一步是测试我的 NewService 类中的方法,所以我再次将测试更改为

def service = new NewSevice()
void "test something"() 
    expect: service.serviceMethod()

当我运行它时,我得到了

| Running 1 unit test...
| Running 1 unit test... 1 of 1
| Failure:  test something(aspera_web.NewServiceSpec)
|  java.lang.NullPointerException
        at aspera_web.NewServiceSpec.test something(NewServiceSpec.groovy:21)
| Completed 1 unit test, 1 failed in 0m 2s
| Tests FAILED  - view reports in C:\Git\aspera_web\target\test-reports

为了更好的衡量,我还直接从 Spock 示例中添加了一个测试

def stack = new Stack()
def "size"() 
    expect: stack.size() == 0

这就像一个魅力......

所以最后我的问题是:

如何测试我自己的服务/控制器方法(如果我将 create-service 替换为 create-controller,我会得到完全相同的结果)

编辑

显然这是 Grails 2.3.0 中的一个错误,请参阅下面的答案。

【问题讨论】:

您必须实例化服务对象才能在测试中使用它。期望 rhs 应该评估为布尔值。 我的英语不是应该的,但我没有用 def service = new NewService() 实例化我的服务,或者你是什么意思? 间接是的。框架和/或注释很可能会创建一个对象实例,然后您可以引用该实例,因此我怀疑您是否需要手动实例化该对象,但读取堆栈跟踪后该服务不存在。谁建议这应该被记录为错误? 就像我在错误报告中提到的那样,当我删除 @Transaction 注释时,服务会被框架实例化,一切正常,这就是我报告它的原因。 【参考方案1】:

解决方案是进入生成的服务类并删除@Transaction 参数。然后由于某种原因,测试中的服务变量被实例化。

我已经为此提交了JIRA report。

解决方法

只需去掉注释并添加行

static transactional = true

改为服务以获得相同的行为。

【讨论】:

【参考方案2】:

如您所见,Grails 2.3 带有用于测试的 Spock 而不是 JUnit。我建议你看at the basics。如果您想要类级别的属性,请查看“字段”会话。

您还可以查看repository of examples。查看service example,您可以看到您的测试已经有一个名为“服务”的变量,Grails 在您使用@TestFor 注释时定义了该变量。

@TestFor(NewService)
class NewServiceSpec 

  def "some description of what the test should do"() 
    expect:
      service.serviceMethod() ...
  

【讨论】:

我将测试更改为 void "test something"() expect: service.serviceMethod() 并将 serviceMethod 更改为返回 true 但我仍然得到 |运行 1 个单元测试... |运行 1 个单元测试... 1 of 1 |失败:测试一些东西(aspera_web.NewServiceSpec)| java.lang.NullPointerException at aspera_web.NewServiceSpec.test something(NewServiceSpec.groovy:18) | 0m 5s完成1个单元测试,1个失败|测试失败 - 在 C:\Git\aspera_web\target\test-reports 中查看报告 请分享您的完整测试。

以上是关于您如何在 grails 2.3 中测试服务或控制器方法的主要内容,如果未能解决你的问题,请参考以下文章

在 Grails 控制台中导入服务?

Grails 2.3 迁移脚本不会在集成测试期间运行

单元测试控制器时无法模拟 Grails 服务方法 - MissingMethodException

如何将角度5的输入值发送到grails 3?

Grails:如何从控制器或服务访问 i18n?

Grails 单元测试问题