会话在某些 rspec 文件中可用,而在其他文件中不可用。怎么会?

Posted

技术标签:

【中文标题】会话在某些 rspec 文件中可用,而在其他文件中不可用。怎么会?【英文标题】:session available in some rspec files and not others. how come? 【发布时间】:2012-07-05 17:46:58 【问题描述】:

在尝试测试某些登录/注销功能时,我想从会话中删除一些信息。我发现我根本无法访问会话。我不断收到错误:nil:NilClass 的未定义方法“会话”。

但令我惊讶的是,我发现我可以从其他 rspec 页面访问会话。其他详细信息如下。我的问题是:为什么我可以从某些文件而不是其他文件访问会话?在下面的第二个示例中,我怎样才能访问会话?

详情 文件:spec/controllers/tenants_controller_spec.rb

require 'spec_helper'

describe TenantsController do
  specify  session[:tag].should == 'abc' 
end

文件:spec/requests/test.rb

require 'spec_helper'

describe 'Test' do
  specify  session[:tag].should == 'abc' 
end

当我通过 rspec 运行第一个文件时,我得到:

Failure/Error: specify  session[:tag].should == 'abc' 
  expected: "abc"
    got: nil (using ==)

哪个好。由于这个原因,这应该会失败。

但是,当我运行第二个文件时,我得到:

 Failure/Error: specify  session[:tag].should == 'abc' 
 NoMethodError:
   undefined method `session' for nil:NilClass

那么为什么 session 在这里是一个未定义的方法呢​​?

【问题讨论】:

【参考方案1】:

您的第二个测试是一个“请求”规范,它是一个集成测试。这些旨在模拟浏览器和您获得的帮助程序,让您单击按钮并填写表单并断言页面上的文本、标签。检查会话对象的抽象级别错误。

如果您想取消身份验证,例如最好通过应用程序。见,例如这里:Stubbing authentication in request spec

知道集成测试是“探索性”或“冒烟”测试,是检查组件之间接缝的高级测试,而不是组件本身的内部测试。它们的编写和维护成本最高。使用控制器规范来验证会话内容并将所有业务逻辑转移到最容易测试的模型中。

【讨论】:

谢谢。这回答了我提出的问题,但不幸的是,答案没有让我到达我想要的地方:(无论如何,我会继续问另一个关于测试登录/注销的问题。 您能解释一下您要解决的问题吗? TDD 社区中有一种观点认为,如果某些东西真的很难测试,那么它的编码方式也可能是错误的。如果您可以在实现之前制定测试用例,则代码往往会更松散耦合。检查我包含的链接,并在此处发布新问题的链接。我看看能不能帮忙。【参考方案2】:

您正在测试两种不同的东西。在第一个测试中,您测试了一个 Rails 控制器,因此 RSpec 为您添加了像 session 这样的帮助器。在第二个测试中,您处于请求测试中,因此 RSpec 不会添加任何与控制器相关的帮助器。

更新

我还没有测试过这个,但是看看source code我认为这应该足够了

include ::RSpec::Rails::ControllerExampleGroup

有关更多信息,请查看 github 上的 rspec-rails 项目。

更新 2

您不应在请求规范中测试 cookie,引用 RSpec docs:

请求规范为 Rails 的集成测试提供了一个精简的包装器,旨在通过整个堆栈驱动行为,包括路由(由 Rails 提供)和没有存根(这取决于您)。

【讨论】:

那么有没有办法让rails在第二种情况下加载必要的帮助程序?怎么样? 更新了答案...如果答案有用,请投票,如果它解决了您的问题,请标记为正确。谢谢。 第二个测试是一个“请求”规范——一个集成测试——它有不同的助手可用,它不仅仅是简单的 Ruby 代码。这里有一个概念上的错误,并且试图将控制器断言和帮助程序硬塞到集成规范中,这会使情况变得更糟。看我的回答。 @WolframArnold 是的,没有看到其中包含文件名。会更新答案 我不同意关于请求规范和 cookie 的说法。这是一个模拟浏览器端交互的集成测试。如果这不是检查控制器是否正确处理与浏览器的 cookie 交互的理想场所,那还有什么更好的地方呢?

以上是关于会话在某些 rspec 文件中可用,而在其他文件中不可用。怎么会?的主要内容,如果未能解决你的问题,请参考以下文章

GetExpressCheckoutDetails 在 asp.net 中返回会话过期(10411 错误)(仅在某些计算机上)

Rspec:测试CSV输出中的行数

为啥在某些语言中使用变量之前需要声明变量,而在其他语言中则不需要? [关闭]

Rspec: everyday-rspec实操: 第10章测试其他功能,第11章TDD

为啥 ping 在某些设备上有效,而在其他设备上无效?

在 for 循环的某些迭代中,字符串的长度为 0,而在其他迭代中则为 0