ruby - 我如何模拟 "does not implement"特定方法的东西?

标签 ruby unit-testing amazon-web-services rspec cucumber

背景:

我正在尝试使用 Cucumber 在 ruby​​ 中围绕 AWS 的接口(interface)进行一些测试驱动(或行为驱动)的开发。

所以,我有一个如下所示的步骤定义:

Then(/^the mock object should have had :(.*?) called, setting "(.*?)" to "(.*?)"$/) do |method, param, value|
  expect(@mock).to receive(method.to_sym).with(hash_including(param, value))
end

@mock 之前设置为:

@mock = instance_double(AWS::AutoScaling::Client)

我在调用此步骤定义时使用如下特征行:

And the mock object should have had :update_auto_scaling_group called, setting "auto_scaling_group_name" to "Some-test-value"

当该步骤运行时,会出现以下错误(省略完整错误,因为我认为这是最相关的部分):

  AWS::AutoScaling::Client does not implement: update_auto_scaling_group (RSpec::Mocks::MockExpectationError)

我确实看到了 checks that RSpec runs (追溯到 from where the RSpec::Mocks::MockExpectationError gets thrown )至少正确地报告了他们从类里面获得的信息:

[1] pry(main)> require 'aws-sdk'
=> true
[2] pry(main)> klass = AWS::AutoScaling::Client
=> AWS::AutoScaling::Client
[3] pry(main)> klass.public_method_defined? "update_auto_scaling_group"
=> false
[4] pry(main)> klass.private_method_defined? "update_auto_scaling_group"
=> false
[5] pry(main)> klass.protected_method_defined? "update_auto_scaling_group"
=> false

然而,如果我们询问一个实际实例,它会让我们知道这是一个它将响应的方法:

[6] pry(main)> x = klass.new
=> #<AWS::AutoScaling::Client::V20110101>
[7] pry(main)> x.respond_to? "update_auto_scaling_group"
=> true

即使它没有说任何事情:

[8] pry(main)> x.respond_to? "bogus"
=> false

第一个问题:

所以...这是 the AWS::AutoScaling::Client code 中的错误吗? (或者实际上,可能是 here ),因为没有以现有检查 ({public,private,protected}_method_defined?) 会返回 true 的方式定义方法?

或者可能是 RSpec 的“ double ”中的一个错误,因为它没有做所有它可以做的检查来试图找出这确实是一个可以在该类的实例中调用的方法?

或者也许这只是我在这里做错了什么?其他?

更一般地说:

我如何为我正在编写的代码编写测试,以确保它使用正确的参数(定义为在我的几张支票中)?是否有其他方法可以编写我的步骤定义来实现此目的?创建我的模拟对象的替代方法?其他?

最佳答案

我找到了一种动态混合我需要模拟的方法的方法

你可以用空方法来做这件事,然后 stub 它们,或者只在混入中包含 stub

require 'rails_helper'

RSpec.describe "users/sessions/new.html.erb", :type => :view do


  it "displays login form" do

    module DeviseUserBits
      def resource
        @_DeviseUserBitsUser ||= User.new
      end
      def resource_name
        :user
      end
      def devise_mapping
        Devise.mappings[:user]
      end
    end

    view.class.include DeviseUserBits

    render

    expect(rendered).to match /form/

  end
end

关于ruby - 我如何模拟 "does not implement"特定方法的东西?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28908726/

相关文章:

c# - 如何知道电子邮件是否被收件人标记为垃圾邮件

ruby - RubySL 中的 Rubinius

ruby - 将多个 gsub 语句重构为 1

javascript - 您如何使用 Resharper 调试 Jasmine 测试?

unit-testing - Vue.js vue-router 无论如何都要测试导航守卫?

javascript - 发送编码后的图像并在解码后上传到 s3

ruby - 删除文件扩展名的最佳方法

ruby - Methods_added 用于单例方法,但不适用于类方法

c# - 如何使用 MSTest/xUnit 框架编写上下文/规范样式的单元测试?

java - AWS Toolkit for Eclipse 安装在 Eclipse Luna 4.4 上失败