简体   繁体   English

Rspec:如何使通过测试失败?

[英]Rspec: How do I make my passing tests fail?

I have a client object in a ruby gem that needs to work with a web service. 我在ruby gem中有一个client对象,需要与Web服务一起使用。 I am testing to verify that it can be properly initialised and throws an error if all arguments are not passed in. 我正在测试以验证是否可以正确初始化它,如果未传递所有参数,则会引发错误。

Here are my specs: 这是我的规格:

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

Here is the gem code: 这是gem代码:

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

and here is the spec_helper method: 这是spec_helper方法:

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

The problem is: I can't find a way to make these tests fail before they pass. 问题是:我找不到使这些测试通过之前失败的方法。 These tests always pass because ruby throws an ArgumentError by default. 这些测试始终会通过,因为默认情况下ruby会引发ArgumentError I don't understand if this is the right approach to TDD. 我不知道这是否是解决TDD的正确方法。 How do I get into a red-green-refactor cycle with this scenario? 在这种情况下,如何进入红绿重构周期?

create_client raises the ArgumentError , because it expects three keyword arguments and you are passing only one: (maybe you should have tested your helper, too) 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)

You could use default values in your helper to overcome this: 您可以在助手中使用默认值来克服此问题:

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)

Finally, you could be more specific regarding the error message: 最后,您可以更详细地说明错误消息:

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

please refer to the answer by Stefan, it's way more proper 请参考斯蒂芬的答案,这样更合适

The proper way would be to mock Client#validate_configuration! 正确的方法是模拟Client#validate_configuration! to do nothing, but here it might be even simpler. 什么都不做,但是在这里可能会更简单。 Put in your test_helper.rb : 放入您的test_helper.rb

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

Frankly, I do not see any reason to force tests to fail before they pass in this particular case. 坦白说,在这种特殊情况下,我认为没有任何理由迫使测试失败。 To follow the TDD, you should have been running tests before validate_configuration! 要遵循TDD,您应该已经 validate_configuration! 之前运行测试validate_configuration! implementation. 实施。 Then those tests would have failed. 然后这些测试将失败。

But since you have implemented it in advance, there is no need to blindly thoughtless follow the rule “test must fail before pass.” 但是,由于您已经预先实现了它,因此无需盲目地遵循“测试必须在通过之前失败”的规则。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM