rspec型号规格let vs工厂



我刚开始测试,还不清楚什么时候应该使用let

我应该在下面的模型测试中使用let来进行延迟加载吗?还是因为每个测试中的数据都有点不同,所以我可以保持原样?正如我在一些例子中看到的,它对控制器测试更为重要,因为:task对每个动作测试都是相同的。

型号规格

require 'rails_helper'
RSpec.describe Task, type: :model do
  describe "model validations" do
    it "has a valid factory" do
      expect(build(:task)).to be_valid
    end
    it "is invalid without executor" do
      expect(build(:task, executor_id: nil)).not_to be_valid
    end
    it "is invalid without assigner" do
      expect(build(:task, assigner_id: nil)).not_to be_valid
    end
    it "is invalid without content" do
      expect(build(:task, content: nil)).not_to be_valid
    end
    it "is invalid without deadline" do
      expect(build(:task, deadline: nil)).not_to be_valid
    end
    it "is invalid with deadline in the past" do
      expect(build(:task, deadline:  Faker::Time.between(DateTime.now - 1, DateTime.now - 2))).not_to be_valid
    end
  end
end

工厂

FactoryGirl.define do
  factory :task do
    content { Faker::Lorem.sentence }
    deadline { Faker::Time.between(DateTime.now + 2, DateTime.now + 3) }
    association :executor, factory: :user
    association :assigner, factory: :user
  end
end

let的好处来自于与您使用的形式不同的测试。想象一下这个群体:

context "completing tasks" do
  let(:completing_a_task){ task.complete }
  context "that aren't due yet" do
    let(:task){ create(:not_due_task) }
    it "should not send an email" do
       expect( TaskMailer ).not_to receive(:deliver_message)
       expect{ completing_a_task }.not_to raise_error
    end
  end
  context "overdue" do
    let(:task){ create(:overdue_task) }
    it "should send an email" do
       expect( TaskMailer ).to receive(:deliver_message)
       expect{ completing_a_task }.not_to raise_error
    end
  end
end

通过允许后期绑定,您可以进行最小的更改,但提供最大的覆盖范围。为了设置测试所需的适当行为,你需要的合作者越多,你就越有可能从let中受益。虽然您不需要在测试套件中特别为DRY驱动,但测试的巨大设置块是一种气味,而let技术是一个很好的工具,即使您的领域很复杂,也可以帮助您争取清晰和简单。我自己的例子中仍然没有合作者,但希望这个概念仍然足够清晰。

我建议保持原样,不要使用let。不要担心DRYing你的测试。它们不相互交互,因此您不会遇到应用程序逻辑中的代码重复问题。

值得一提的是,您可以使用shoulda-matchers gem来完成您所拥有的:https://github.com/thoughtbot/shoulda-matchers

describe Task do
  describe "validations" do
    it { is_expected.to validate_presence_of(:content) }
    it { is_expected.to validate_presence_of(:deadline) }
  end
end

最新更新