Rspec测试:它{should respond_to()}

时间:2012-02-02 19:56:22

标签: ruby unit-testing rspec2

如果您有一个属性列表,您正在测试它们的存在,并且您有以下内容:

before do
  @attr = Employee.new(name: "One",
                       email: "onetwo@three.com")
end

subject { @attr }

it { should respond_to(:name) }
it { should respond_to(:email) }

it { should be_valid }

然后你可以测试反向,即如果这些属性是空白的:

it { should_not respond_to(:reverse, :blank) }
it { should_not be_valid }

我确实尝试了上述内容,但即使在阅读this discussion之后,我也无法理解这些问题。

有没有人知道如何使用相同的初始化来测试状态,然后转身并测试空白属性?

2 个答案:

答案 0 :(得分:22)

我认为你误解了respond_to在测试中的作用。当你这样做

it { should respond_to(:name) }

你断言@attr.respond_to(:name)返回true,意味着该方法存在,而不是它返回一个值。如果您想测试返回的值,您可以执行以下操作:

its(:name){ should be_present }

这将确保调用name方法的结果返回非假的非空值。然后,当你逆转那个测试时

its(:name){ should_not be_present }

您断言name方法返回空白。您必须为第二个测试创建不同的设置,因为您正在测试处于不同状态的对象。

答案 1 :(得分:0)

您对用户对象的单独测试应该更像是:

it "should have an email attribute" do
  @attr.should respond_to(:email) }
end

但是,如果您正在测试一个课程,我是否可以根据您的测试提出更多建议:

before (:each) do
  @attr = {name: "One", email: "onetwo@three.com"}
end

然后你的第一个测试确保创建工作如下:

it "should create a new instance given valid attributes" do
  Employee.create!(@attr)
end

一旦确定了您的工作,就可以继续进行其他测试并让员工自动创建:

describe "Attributes and method tests" do
  before (:each) do
    @employee = Employee.create(@attr)
  end

  it "should have a name attribute" do
    @employee.should respond_to(:name)
  end

  it "should have an email attribute" do
    @employee.should respond_to(:email) }
  end

  # etc... (to test other attributes or methods)
end

要回答关于逆转测试的问题,并指定如果属性为空,则无效,我会尝试这样的事情。如果您对存在进行了验证,那么这些测试会很好:

it "should not be valid with a blank email" do
  Employee.new(@attr.merge(:email => '').should_not be_valid
end

it "should not be valid with a blank name" do
  Employee.new(@attr.merge(:name => '').should_not be_valid
end