Unit Testing validates presence of odd behaviour

ぐ巨炮叔叔 提交于 2020-01-02 14:06:10

问题


I'm trying out the whole TDD and I'm running into a problems with validate presence. I have a model called Event and I want to ensure that when an Event is created that a title a price and a summary exists.

Unit Test Code

class EventTest < ActiveSupport::TestCase

  test "should not save without a Title" do
    event = Event.new
    event.title = nil
    assert !event.save, "Save the Event without title"
  end

  test "should not save without a Price" do
    event = Event.new
    event.price = nil
    assert !event.save, "Saved the Event without a Price"
  end

  test "should not save without a Summary" do
    event = Event.new
    event.summary = nil
    assert !event.save, "Saved the Event without a Summary"
  end

end

I run the test I get 3 FAILS. Which is Good. Now I want to to just get the title test to pass first with the following code in the Event model.

class Event < ActiveRecord::Base

  validates :title, :presence => true

end

When I re-run the test I get 3 PASSES where I would think I should have gotten 1 PASS and 2 FAILS. Why am I getting 3 PASSES?


回答1:


I have two test helper methods that can make this sort of thing easier to diagnose:

def assert_created(model)
  assert model, "Model was not defined"
  assert_equal [ ], model.errors.full_messages
  assert model.valid?, "Model failed to validate"
  assert !model.new_record?, "Model is still a new record"
end

def assert_errors_on(model, *attrs)
  found_attrs = [ ]

  model.errors.each do |attr, error|
    found_attrs << attr
  end

  assert_equal attrs.flatten.collect(&:to_s).sort, found_attrs.uniq.collect(&:to_s).sort
end

You'd use them in cases like this:

test "should save with a Title, Price or Summary" do
  event = Event.create(
    :title => 'Sample Title',
    :price => 100,
    :summary => 'Sample summary...'
  )

  assert_created event
end

test "should not save without a Title, Price or Summary" do
  event = Event.create

  assert_errors_on event, :title, :price, :summary
end

This should show if you're missing a validation that you expected and will also give you feedback on specific validations that have failed when not expected.




回答2:


When you created the model with Event.new, all attributes initially have a value of nil. This means that all 3 attributes you are checking are already nil (so event.title = nil and event.price = nil don't actually do anything). Since title has been marked for validation to ensure its presence, unless you set title to something other than nil, you will not be able to save the model.

Perhaps try adding this to your test class:

setup do
  @event_attributes = {:title => "A title", :price => 3.99, :summary => "A summary"}
end

Then instead of:

event = Event.new
event.title = nil

Use:

event = Event.new(@event_attributes.merge(:title => nil))

Do the same for all your tests (substituting :title with whatever attribute you are validating presence for)

Also, there's no reason to call save to test for a valid state. You can just call event.valid? to avoid trips to the database where not needed.



来源:https://stackoverflow.com/questions/8993068/unit-testing-validates-presence-of-odd-behaviour

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!