【问题标题】:Ruby on Rails 4 - Rspec: count should have been changed by 1, but was changed by 0Ruby on Rails 4 - Rspec:计数本应更改为 1,但更改为 0
【发布时间】:2014-03-15 17:55:50
【问题描述】:

我目前正在开发一个 Ruby on Rails 应用程序,而且我是测试新手。几天前,我开始使用 gems rspec-railsfactory_girl_railsfaker 编写测试。

为模型验证编写测试非常简单,但现在我一直在编写控制器测试。 我有一个简单的类“Message”,是我使用脚手架命令创建的。

架构:

create_table "messages", force: true do |t|
  t.string   "name"
  t.string   "email"
  t.string   "text"
  t.datetime "created_at"
  t.datetime "updated_at"   end

当我尝试运行以下测试时..

spec/controllers/messages_controller_spec.rb:

  describe "POST create" do
    describe "with valid params" do
      it "creates a new Message" do
        expect {
          post :create, FactoryGirl.create(:message)
        }.to change(Message, :count).by(1)
      end
    end
  end

..我收到此错误消息..

MessagesController POST 创建 具有有效参数 创建一条新消息 (FAILED - 1)

失败:

1) MessagesController POST create with valid params 创建一个新的 信息 失败/错误:期望 { count 应该改了 1,但是改了 0

..通过使用这个工厂:

spec/factories/message.rb:

require "faker"

FactoryGirl.define do
  factory :message do |m|
    m.name { Faker::Name.name }
    m.email { Faker::Internet.email }
    m.text { Faker::Lorem.sentences }
  end
end

我一直在寻找 HOURS 的答案 - 但到目前为止,我还没有找到适合我的解决方案。我希望那里的任何人都可以帮助我!

谢谢!

这是我的模型:(但即使我删除所有验证,我也会收到相同的错误消息)

class Message < ActiveRecord::Base
  validates :name, :email, :text,
    presence: { 
      value:  :true,
      message: "ist ein Pflichtfeld"
    }

    validates :name, length: { maximum: 50,
        too_long: "ist zu lang" }

    validates :email, length: { maximum: 50,
        too_long: "ist zu lang" }

    validates :text, length: { maximum: 10000,
        too_long: "ist zu lang" }

end

这是我的创建操作:

  def create

    @message = Message.new(message_params)
    respond_to do |format|
      if @message.save
        format.html { redirect_to action: 'new' }
        format.json { render action: 'show', status: :created, location: @message }
      else
        format.html { render action: 'new' }
        format.json { render json: @message.errors, status: :unprocessable_entity }
      end
    end
  end

函数:message_params

def message_params
  params.require(:message).permit(:name, :email, :text)
end

【问题讨论】:

  • 可以展示消息模型吗?
  • 应该在哪里创建Message?在 rspec 中(调用 FactoryGirl.create(:message) 或在控制器中(调用 post :create,...)?
  • 这是我的消息模型的样子:class Message

标签: ruby-on-rails ruby rspec ruby-on-rails-4 factory-bot


【解决方案1】:

使用attributes_for 方法,该方法返回可用于构建消息实例的属性散列。

 describe "POST create" do
    describe "with valid params" do
      it "creates a new Message" do
        expect {
          post :create, FactoryGirl.attributes_for(:message) ## Use attributes_for
        }.to change(Message, :count).by(1)
      end
    end
  end

FactoryGirl.create(:message) 实际上会在messages 表中保存一条记录。 对于控制器测试,您只需传递属性哈希值,post :create 将调用 MessagesController#create 操作,然后将记录保存在数据库中。

编辑

m.text { Faker::Lorem.sentences } 替换为m.text { Faker::Lorem.paragraph }。 因为sentences 返回一个字符串数组,而模型message 中的字段text 需要一个字符串。这将导致错误并无法保存记录。

require "faker"

FactoryGirl.define do
  factory :message do |m|
    m.name { Faker::Name.name }
    m.email { Faker::Internet.email }
    m.text { Faker::Lorem.paragraph } ## Use paragraph instead of sentences
  end
end

【讨论】:

  • 感谢您的回答,但我仍然收到此错误:Failure/Error: expect { count should have been changed by 1, but was changed by 0
  • 请分享Message 模型和MessagesController#create 操作。
  • 这是我的模型:class Message
  • 也分享 create_params 方法。将其添加到问题中,而不是评论中,使其更具可读性。
  • 哦,抱歉-将其添加到问题中...任何想法? :(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-17
  • 1970-01-01
  • 1970-01-01
  • 2018-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多