【问题标题】:All rspec tests passing when they should not (Rails 3.2, Rspec)所有不应该通过的 rspec 测试(Rails 3.2,Rspec)
【发布时间】:2013-09-11 18:49:58
【问题描述】:

我正在构建一个日常交易轨道应用程序,并且我按照 M. Hartl 教程设置了一些 rspec 测试。

对于用户来说,它们工作得很好。

但是现在我已经将它用于模型 Eals 并且所有的都通过了,而他们不应该这样做。例如,在我的模型中,我设置了标题不能超过 200 个字符(注意:在我看来,当我尝试将标题设置得比这更长时,它会起作用并提醒我这是不可能的)

但是当我进行测试时,无论我尝试在标题测试中使用 long = "a" * 50、a * 201 甚至 a * 10000 进行标题字符长度测试,它总是通过!有一个大问题我没能找到。 实际上所有其他测试都有相同的问题:它们总是通过!

这是我的模型/deal.rb

class Deal < ActiveRecord::Base

 belongs_to :admin_user

 attr_accessible :url_path, 
                 :country, 
                 :title,
                 :description,
                 :twitter_msg,
                 :admin_user_id

 validates :url_path,
          presence: true,
          uniqueness: { :case_sensitive => false }
 validates :country, 
          :inclusion => {  :in => ['France', 'Germany', 'United States'],
                           :message => "%{value} is not a valid country. " }
 validates :title,
          presence: true,
          length: { maximum: 200, 
                    :message => "Your title has %{value} characters but must be shorter than 200 characters" }  
validates :description,
          presence: true,
          length: { maximum: 500,
                    :message => "Your title has %{value} characters but must be shorter than 500 characters" } 
validates :twitter_msg,
         presence: true,
         uniqueness: { :case_sensitive => false }


validates :admin_user_id, presence: true

还有我的 deal_spec.rb:

require 'spec_helper'

describe Deal do

let(:admin_user) { FactoryGirl.create(:admin_user) }

before (:each) do
    @attr = {       url_path: "lorem ipsum",
                    country:"France",                        
                    title:  "lorem ipsum", 
                    description:"lorem ipsum",
                    twitter_msg:"lorem ipsum",
                                     }
end

it { should respond_to(:url_path) }
it { should respond_to(:country) }
it { should respond_to(:title) }
it { should respond_to(:description) }
it { should respond_to(:twitter_msg) }

describe "title test" do

it "should reject deals with title that is too long" do
  long = "a" * 50
  hash = @attr.merge(:title => long)
  Deal.new(hash).should_not be_valid
end

[other tests] 

 end #end of title test

如果有人能帮助我理解这一点,那就太好了,我已经花了几个小时没有任何线索。

在听从某人的建议后,我改变了我的测试

Deal.new(hash).should have(1).error_on(:title)

    describe "test" do

    it "should reject games with title that is too long" do
      long = "a" * 250
      hash = @attr.merge(:title => long)
      Game.new(hash).should have(1).error_on(:title)
    end
    end

但现在它一直在过去,即它告诉我无论我是否输入 long= "a" * 5, long="a" * 300...,我的标题都有一个错误...

【问题讨论】:

  • 你试过long = "a" * 201而不是long = "a" * 200吗?
  • @YevgeniyAnfilofyev 我尝试输入 * 200、a* 50(低于 200)、a * 500(高于 200)......它们都通过了。好像我的测试还没有真正完成,它说一直通过
  • 启动rails c,并使用这些属性创建一个新的Deal 对象并检查它。无论出于何种原因,你都没有得到你所期望的结果,直接玩这个对象并找出答案要容易得多。
  • 尝试将正确的值填充到具有presence: true的所有字段中。
  • 重新更新 - 模型中的验证不仅仅针对视图。每当您尝试通过控制器、控制台、迁移 - 任何方式创建或更新模型时,都会应用它。在rails c 中,输入deal = Deal.new,然后输入deal.valid?。如果返回 false,则验证正在工作。 deal.errors 会告诉你出了什么问题。

标签: ruby-on-rails ruby ruby-on-rails-3 unit-testing rspec


【解决方案1】:

这不是使用 RSpec 测试验证的正确方法,因为它不会告诉您为什么对象无效。它可能是无效的,因为您缺少与您正在测试的属性完全不同的属性。您应该使用have(x).errors_on(y) 断言:

Deal.new(hash).should have(1).error_on(:title)

【讨论】:

  • 这是真的,从来没想过(我是 RoR 的新手)。我肯定会使用你的语法,它很棒,但它不断传递我输入的任何值(a* 5、a* 200、a* 4000),它一直在传递!准确地说,它一直告诉我在所有情况下我都有 1 个错误!
【解决方案2】:

我建议使用shoulda_matchers 来测试这些东西

【讨论】:

    【解决方案3】:

    你能试试下面的代码吗?它应该会提示您哪些属性无效(以及原因):

    it "..." do
      d = Deal.new(@attr)
      d.valid?
      puts d.errors.full_messages
    end
    

    【讨论】:

      【解决方案4】:

      admin_user_id 不在您的 @attr 哈希中。但是,在您的 Deal 模型上它是强制性的 - 因此您的测试总是通过,因为新交易无效。与标题的长度无关。

      【讨论】:

      • 我已经写了,但似乎没有任何改变
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多