Rspec:如何让我的通过考试失败?

时间:2016-12-15 07:30:00

标签: ruby rspec configuration rubygems

我在ruby gem中有一个client对象,需要使用Web服务。我正在测试验证它是否可以正确初始化并在未传入所有参数时抛出错误。

以下是我的规格:

describe 'Contentstack::Client Configuration' do
  describe ":access_token" do
    it "is required" do
      expect { create_client(access_token: nil) }.to raise_error(ArgumentError)
    end
  end

  describe ":access_key" do
    it "is required" do
      expect { create_client(access_key: nil) }.to  raise_error(ArgumentError)
    end
  end

  describe ":environment" do
    it "is required" do
      expect { create_client(environment: nil) }.to  raise_error(ArgumentError)
    end
  end
end

这是宝石代码:

module Contentstack

  class Client
    attr_reader :access_key, :access_token, :environment

    def initialize(access_key:, access_token:, environment:)
      @access_key = access_key
      @access_token = access_token
      @environment = environment

      validate_configuration!
    end

    def validate_configuration!
      fail(ArgumentError, "You must specify an access_key")  if access_key.nil?
      fail(ArgumentError, "You must specify an access_token")  if access_token.nil?
      fail(ArgumentError, "You must specify an environment")  if environment.nil?
    end
  end

end

这是spec_helper方法:

def create_client(access_token:, access_key:, environment:)
  Contentstack::Client.new(access_token: access_token, access_key: access_key, environment: environment)
end

问题是:我找不到让这些测试在通过之前失败的方法。这些测试总是通过,因为ruby默认会抛出ArgumentError。我不明白这是否是TDD的正确方法。如何使用此方案进入红绿重构循环?

2 个答案:

答案 0 :(得分:3)

create_client引发ArgumentError,因为它需要三个关键字参数而你只传递一个:(也许你应该测试你的帮助器)

def create_client(access_token:, access_key:, environment:)
  # intentionally left empty
end

create_client(access_key: nil)
# in `create_client': missing keywords: access_token, environment (ArgumentError)

您可以在助手中使用默认值来克服这个问题:

def create_client(access_token: :foo, access_key: :bar, environment: :baz)
  Contentstack::Client.new(access_token: access_token, access_key: access_key, environment: environment)
end

create_client(access_key: nil)
# in `validate_configuration!': You must specify an access_key (ArgumentError)

最后,您可以更具体地了解错误消息:

expect { ... }.to raise_error(ArgumentError, 'You must specify an access_key')

答案 1 :(得分:1)

请参考Stefan的答案,这样更合适

正确的方法是模仿Client#validate_configuration!什么都不做,但在这里它可能更简单。放入test_helper.rb

Client.prepend(Module.new do
  def validate_configuration!; end
end)

坦率地说,我没有看到任何理由强迫测试在通过这个特殊情况之前失败。要遵循TDD,您应该在 validate_configuration!实现之前运行测试。然后那些测试就会失败。

但是既然你事先已经实现了它,就没有必要盲目地不加思索地遵循“测试必须在通过之前失败”的规则。