简体   繁体   English

如何测试 controller 中的实例变量?

[英]How do I test an instance variable in a controller?

A couple of my mentors have told me to test a piece of code with controller spec even though the contents are being tested by some request specs.我的几个导师告诉我使用 controller 规范测试一段代码,即使某些请求规范正在测试内容。 I am wondering if I can test whether an instance variable like @user can be set to someObject or nil from within an rspec controller test?我想知道是否可以在 rspec controller 测试中测试像@user这样的实例变量是否可以设置为someObjectnil

I've tried a couple different ways to test this so far, but my skills regarding rspec testing are to say the least, elementary.到目前为止,我已经尝试了几种不同的方法来测试它,但我在 rspec 测试方面的技能至少可以说是初级的。 The first thing I tried was mocking out the current_user and the 'User.get_from_auth_user(current_user).我尝试的第一件事是 mocking 输出 current_user 和 'User.get_from_auth_user(current_user)。 The mocked object prints fine and outputs.模拟的 object 打印良好并输出。 The problem is... I want to be able to say something like expect(@user).to equal(mockedUser) but this never seems to work.问题是......我希望能够说类似expect(@user).to equal(mockedUser)但这似乎永远不会奏效。 I always get something like:我总是得到类似的东西:

Expect does not equal received
expected is nil
received is { someMockedObject }

Here is the code I want to test.这是我要测试的代码。

class ApplicationController < ActionController::Base
  before_action :set_user

  def set_user
    return if current_user.nil?

    @user = User.get_from_auth_user(current_user)
  end
end

I want to know if I'm going down the right path or what would be the better alternative to fully test this chunk of code.我想知道我是否走在正确的道路上,或者什么是完全测试这段代码的更好选择。 I feel like the answer should be a simple one.我觉得答案应该很简单。

Your mentors are being stupid.你的导师很愚蠢。 While it can be good to understand controller specs as they are everywhere in legacy applications adding them to new applications is not a good practice.虽然了解 controller 规范可能会很好,因为它们在旧应用程序中无处不在,但将它们添加到新应用程序并不是一个好习惯。

For new Rails apps: we don't recommend adding the rails-controller-testing gem to your application.对于新的 Rails 应用程序:我们不建议将 rails-controller-testing gem 添加到您的应用程序中。 The official recommendation of the Rails team and the RSpec core team is to write request specs instead. Rails 团队和 RSpec 核心团队的官方建议是改为编写请求规范。 Request specs allow you to focus on a single controller action, but unlike controller tests involve the router, the middleware stack, and both rack requests and responses.请求规范允许您专注于单个 controller 操作,但与 controller 不同的是,测试涉及路由器、中间件堆栈以及机架请求和响应。 This adds realism to the test that you are writing, and helps avoid many of the issues that are common in controller specs.这增加了您正在编写的测试的真实性,并有助于避免 controller 规范中常见的许多问题。

DHH explains pretty well what is wrong with testing the instance variables of your controller and what you should be doing instead: DHH 很好地解释了测试 controller 的实例变量有什么问题以及您应该做什么:

Testing what instance variables are set by your controller is a bad idea.测试您的 controller 设置了哪些实例变量是一个坏主意。 That's grossly overstepping the boundaries of what the test should know about.这严重超出了测试应该知道的范围。 You can test what cookies are set, what HTTP code is returned, how the view looks, or what mutations happened to the DB, but testing the innards of the controller is just not a good idea.您可以测试设置了什么 cookies,返回什么 HTTP 代码,视图的外观,或者数据库发生了什么突变,但是测试 controller 的内部结构并不是一个好主意。

Which is why assigns was extracted to a separate gem.这就是为什么assigns提取到单独的 gem 的原因。 It all boils down to testing what your code does - not how it does it.这一切都归结为测试你的代码做了什么——而不是它是怎么做的。

See:看:

Use assigns(:user) to get the instance variable @user .使用 assigns assigns(:user)获取实例变量@user In your spec, @user is a variable on that test context, it's not the same @user from the controller.在您的规范中, @user是该测试上下文中的一个变量,它与@user中的 @user 不同。

https://relishapp.com/rspec/rspec-rails/docs/controller-specs https://relishapp.com/rspec/rspec-rails/docs/controller-specs

In addition to @chans and @arieljuod answers, it worth to mention in order to use assigns in your specs, you need to set up rails-controller-testing gem, because assigns is deprecated starting from Rails 5.除了@chans@arieljuod 的答案,值得一提的是,为了在您的规范中使用assigns ,您需要设置rails-controller-testing gem,因为从 Rails 5 开始不推荐使用assigns

# File actionpack/lib/action_dispatch/testing/test_process.rb, line 6
def assigns(key = nil)
  raise NoMethodError,
    "assigns has been extracted to a gem. To continue using it,
    add `gem 'rails-controller-testing'` to your Gemfile."
end

The controller test case looks like this controller 测试用例如下所示

describe 'GET #set_user' do
  let!(:mock_user) { 
      @mockuserObj = { id: 1, name: "username" }
  }
  before(:each) do
    controller.instance_variable_set(:current_user, @mockuserObj)
    get :set_user
  end
  context 'when current_user is present' do
    it "sets the current user" do
      expect(assigns(:user)).to eq(@mockuserObj)
    end
  end
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用rspec在我的控制器的新操作中测试实例变量的赋值? - How do I test the assignment of an instance variable in the new action of my controller with rspec? 在Rails中,如何测试在控制器中对Model实例所做的修改? - In Rails how do I test modifications to an instance of a Model that are made in a controller? 如何在控制器中的多个操作中存储实例变量? - How do I store an instance variable across multiple actions in a controller? 如何使用Rspec测试控制器内的局部变量? - How do I test a local variable inside a controller with Rspec? 如果授权取决于实例变量,如何使用Pundit授权控制器动作? - How do I authorize a controller action with Pundit if authorization depends on an instance variable? 如何使用rspec测试我的邮件程序中是否设置了实例变量? - how do I test that an instance variable is set in my my mailer with rspec? 将实例变量传递给rspec中的控制器测试? - Pass instance variable to controller test in rspec? Rails 3-如何测试控制器模块? - Rails 3 - How do I test a controller module? 如何在控制器中测试实例变量的可用性? - How can I test the availability of instance variables in my controller? 如何在我的rspec测试中设置变量,以便控制器可以使用它来进行查询? - How do I set a variable in my rspec test so that it can be used by the controller for a query?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM