小编Jay*_*rio的帖子

如何测试是否在RSpec中调用方法但不覆盖返回值

已经类似的问题,但它们都会覆盖返回值,nil除非.and_return被调用

问题

我想知道是否有办法只检查一个方法是否被调用使用expect_any_instance_of(Object).to receive(:somemethod)并且它正常运行而不会覆盖或影响返回值.somemethod.

  • rspec的-3.4.0
  • 铁轨4.2

考虑以下:

# rspec
it 'gets associated user' do
  expect_any_instance_of(Post).to receive(:get_associated_user)
  Manager.run_processes
end

# manager.rb
class Manager
  def self.run_processes
    associated_user = Category.first.posts.first.get_associated_user
    associated_user.destroy!
  end
end
Run Code Online (Sandbox Code Playgroud)

上面的规范虽然会起作用,因为它:get_associated_user被称为run_processes,但它NoMethodError: undefined method 'destroy!' for NilClass正好引起,因为我嘲笑了:get_associated_userPost的任何实例.

我可以添加一个.and_return方法,expect_any_instance_of(Post).to receive(:get_associated_user).and_return(User.first)以便它可以工作而不会引发该错误,但这已经是一个模拟的返回值(可能会影响它下面的其余代码),而不是它应该在当时返回的正确的期望值该方法被调用.

但是.and_return(correct_user) ,我可以指定correct_user用户在哪里将返回相同的返回值,就好像它已正常运行一样.但是,这需要我模拟序列中的每个返回值,Category.first.posts.first.get_associated_user以便它能正常工作.实际问题比上面复杂得多,因此在我的情况下,存根不是真正可行的解决方案.

rspec ruby-on-rails

6
推荐指数
1
解决办法
1789
查看次数

如何列出类的所有方法(不是扩展和包含的方法)

使用Ruby 2.2.1,如何列出仅在该类/文件中定义的类的所有方法(最好是字符串数组),其中includeextend方法被过滤掉.我想区分类和实例方法.

目前,我可以使用所有未使用的MyClass.methods(false)方法,但这仍然包括作为include模块一部分的方法.

明确地说,我有:

class MyClass < BaseClass
  extend AnotherBaseClass
  include MyModule

  def foo
  end

  def bar
  end
end
Run Code Online (Sandbox Code Playgroud)

我想得到:

somecodethatreturnssomething
#=> ['foo', 'bar']
# Not including BaseClass, AnotherBaseClass, and ModuleClass methods
Run Code Online (Sandbox Code Playgroud)

更新:

当我在一个单独的irb控制台中运行它时,@ Waker Maker的答案是正确的.不过,我仍然有一个问题,特别是我,包括ActionView::Helpers::UrlHelperMyClass.我总是得到额外的方法:default_url_options?,default_url_options=,和default_url_options.我认为无论Rails与否都包含相同的行为,所以我没有用Rails标记这个问题.

我甚byebug至在文件的末尾添加了MyClass,以便我可以检查类并运行MyClass.singleton_methods(false)或运行MyClass.instance_methods(false).但他们仍然包括这三种不需要的方法.

我可以手动从数组中删除这三个额外的方法,所以我可以得到我的类的方法的动态列表,但我只是害怕将来我的应用程序将破坏,如果有更新或将添加新方法的东西班级(不知不觉).

更新:

这3种方法只在Rails 3(我正在研究的项目)中添加,但不在Rails 4中(因为我和@Wand Maker已经测试过).

这是确切的代码(我已经删除了所有内容,但仍然得到相同的结果/问题)

# lib/my_class.rb
class MyClass
  include ActionView::Helpers::UrlHelper

  def welcome
    puts 'Hello …
Run Code Online (Sandbox Code Playgroud)

ruby ruby-on-rails ruby-on-rails-3.2 ruby-2.2

4
推荐指数
1
解决办法
1407
查看次数

使子实例无法访问实例方法

鉴于:

class Base
  def foo
    puts 'foo!!!'
  end
end

class Ball < Base
end
Run Code Online (Sandbox Code Playgroud)

我想要:

  1. Ball.new.foo返回错误:No Method Found.
  2. Base.new.foo归来:foo!!!.

我的尝试是:

  • 我能做到protected def foo,所以1.工作.但是这不适用于2.
  • 我可以像上面给出的那样做,所以2.工作.但是1.不起作用.

任何想法如何使1.和2.工作?

问题的背景

我有一个ApplicationController动作def routing_error来处理所有剩余的未定义的路线.这个问题是所有继承的所有其他控制器ApplicationController也继承了那个动作,我希望它不是.我可以用动作创建一个单独的控制器,def routing_error但我觉得它有点矫枉过正,并且只是想知道是否有另一种解决方法.

ruby oop inheritance visibility

3
推荐指数
1
解决办法
84
查看次数

调用方法时如何传递所有局部变量

我想知道在调用方法时是否有一种简单的方法来传递所有局部变量,而不是逐个传递它们作为参数.我想要以下内容:

class Greeting
  def hello
    message = 'HELLO THERE!'
    language = 'English'
    say_greeting
  end

  def konnichiwa
    message = 'KONNICHIWA!'
    language = 'Japanese'
    say_greeting
  end

  private def say_greeting
    puts message
  end
end

Greeting.new.hello
Run Code Online (Sandbox Code Playgroud)

显示HELLO THERE!.但它返回一个错误:NameError: undefined local variable or method 'message'.

我试图local_variables将所有局部变量作为符号数组.但我似乎无法访问实际变量,因为似乎没有类似的Ruby方法local_variable_get.

问题的背景

在我的Rails应用程序中,我有一个控制器,它有三种不同视图文件的更新方法.所有这些行为完全相同(它们都会更新资源,显示错误,如果有的话等).他们唯一的主要区别是

  1. 不成功时要呈现的模板
  2. 成功时重定向url
  3. 闪存成功消息

我只有三个变量,所以将它们作为参数传递确实很容易,但我只是想知道是否有一个优雅的解决方案.

ruby local-variables

3
推荐指数
1
解决办法
1391
查看次数

在rails-api中PUT或PATCH`_method`参数不起作用或不被尊重

域名注册地址:

使用rails --api预期的 rails 作为PUT方法从POST and params[:_method]='put'路由,但路由为POST

鉴于:

  • 导轨 4.2.8
  • 导轨 API 0.4.1

考虑以下:

配置/routes.rb:

resources :sessions, do
  put 'authenticate', on: :collection
end
Run Code Online (Sandbox Code Playgroud)

一些客户端 HTML 文件:

<form action='http://localhost:3000/sessions/authenticate' method='post'>
  <input type='hidden' name='_method' value='put'>
  ...
</form>
Run Code Online (Sandbox Code Playgroud)

...在表单提交时:

rails server 输出:

Started POST "/sessions/authenticate" for ::1 at 2018-03-07 11:20:21 +0000
No route matches [POST] "/sessions/authenticate" excluded from capture: DSN not set

ActionController::RoutingError (No route matches [POST] "/sessions/authenticate"):
  actionpack (4.2.8) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  actionpack (4.2.8) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call' …
Run Code Online (Sandbox Code Playgroud)

ruby-on-rails rails-api

3
推荐指数
1
解决办法
1267
查看次数

如何在Ruby on Rails中的DB对象之前获取100个项目

我有一个Message模特.我想在说之前获取100个项目ID = 654,因此如果数据库中没有丢失ID,我想要获得的ID是553..653.

我能想出的最好的东西是这样的,Message.where(:id => myID-100..myID)但问题是,如果数据库中缺少ID,请说584,585,586,588,589,592,593 ...而且我之前只想要100个项目,并且不是ID范围.

任何帮助将非常感激.

ruby ruby-on-rails

2
推荐指数
1
解决办法
89
查看次数

用什么方法检查:空白?&&!false?

我正在寻找一种方法(最好只有一个Rails或Ruby方法),它将验证变量是否为空但不是false(因为我有一些不应该为空的布尔变量?== true,因为它们有值).

说我有四种类型:nil, '', 0, false.

我正在寻找一个相当于以下的简单方法:

(var.nil? || var == '') && var !== false

这是我能想到的最简单的:

var.blank? && var !== false

如果没有其他方法,那么我想我只需要为此创建一个自定义方法.

ruby ruby-on-rails

-3
推荐指数
1
解决办法
115
查看次数