| |   |
| 5 | 5 | used it, and they will now break. Just replace the metaclass call with (class << self; self; end) |
| 6 | 6 | and all will be well. |
| 7 | 7 | |
| 8 | * Improved stub_model such that new_record? does "the right thing" |
| 8 | 9 | * Patch from Pat Maddox to get integrate_views to work in nested example groups. |
| 9 | 10 | * Patch from Pat Maddox to get controller_name to work in nested example groups. |
| 10 | 11 | * Patch from Corey Haines to add include_text matcher (rspec_on_rails) |
| toggle raw diff |
--- a/rspec/CHANGES
+++ b/rspec/CHANGES
@@ -5,6 +5,7 @@ Note: we've removed the metaclass method from Object. There were some generated
used it, and they will now break. Just replace the metaclass call with (class << self; self; end)
and all will be well.
+* Improved stub_model such that new_record? does "the right thing"
* Patch from Pat Maddox to get integrate_views to work in nested example groups.
* Patch from Pat Maddox to get controller_name to work in nested example groups.
* Patch from Corey Haines to add include_text matcher (rspec_on_rails) |
| |   |
| 52 | 52 | m |
| 53 | 53 | end |
| 54 | 54 | |
| 55 | | # Creates an instance of a +model_class+ that is prohibited |
| 56 | | # from accessing the database. It comes with an id, although |
| 57 | | # you can stub the id explicitly. |
| 55 | # :call-seq: |
| 56 | # stub_model(Model) |
| 57 | # stub_model(Model, hash_of_stubs) |
| 58 | # |
| 59 | # Creates an instance of +Model+ that is prohibited from accessing the |
| 60 | # database. For each key in +hash_of_stubs+, if the model has a |
| 61 | # matching attribute (determined by asking it, which it answers based |
| 62 | # on schema.rb) are simply assigned the submitted values. If the model |
| 63 | # does not have a matching attribute, the key/value pair is assigned as |
| 64 | # a stub return value using RSpec's mocking/stubbing framework. |
| 65 | # |
| 66 | # new_record? is overridden to return the result of id.nil? This means |
| 67 | # that by default new_record? will return false. If you explicitly set |
| 68 | # :id => nil, the object will behave as you would expect, and return |
| 69 | # true for new_record? |
| 58 | 70 | # |
| 59 | 71 | # == Examples |
| 60 | 72 | # |
| 61 | 73 | # stub_model(Person) |
| 62 | 74 | # stub_model(Person, :id => 37) |
| 63 | 75 | # stub_model(Person) do |person| |
| 64 | | # person.first_name = "David" |
| 76 | # model.first_name = "David" |
| 65 | 77 | # end |
| 66 | 78 | def stub_model(model_class, stubs = {}) |
| 67 | 79 | id = @@model_id |
| … | … | |
| 82 | 82 | :id => id |
| 83 | 83 | }.merge(stubs) |
| 84 | 84 | returning model_class.new do |model| |
| 85 | | add_stubs(model, stubs) |
| 85 | model.id = stubs.delete(:id) |
| 86 | 86 | (class << model; self; end).class_eval do |
| 87 | 87 | def connection |
| 88 | 88 | raise IllegalDataAccessException.new("stubbed models are not allowed to access the database") |
| 89 | 89 | end |
| 90 | def new_record? |
| 91 | id.nil? |
| 92 | end |
| 90 | 93 | end |
| 94 | stubs.each do |k,v| |
| 95 | if model.has_attribute?(k) |
| 96 | model[k] = stubs.delete(k) |
| 97 | end |
| 98 | end |
| 99 | add_stubs(model, stubs) |
| 91 | 100 | yield model if block_given? |
| 92 | 101 | end |
| 93 | 102 | end |
| 94 | | |
| 95 | 103 | #-- |
| 96 | 104 | # TODO - Shouldn't this just be an extension of stub! ?? |
| 97 | 105 | # - object.stub!(:method => return_value, :method2 => return_value2, :etc => etc) |
| toggle raw diff |
--- a/rspec_on_rails/lib/spec/rails/example/rails_example_group.rb
+++ b/rspec_on_rails/lib/spec/rails/example/rails_example_group.rb
@@ -52,16 +52,28 @@ module Spec
m
end
- # Creates an instance of a +model_class+ that is prohibited
- # from accessing the database. It comes with an id, although
- # you can stub the id explicitly.
+ # :call-seq:
+ # stub_model(Model)
+ # stub_model(Model, hash_of_stubs)
+ #
+ # Creates an instance of +Model+ that is prohibited from accessing the
+ # database. For each key in +hash_of_stubs+, if the model has a
+ # matching attribute (determined by asking it, which it answers based
+ # on schema.rb) are simply assigned the submitted values. If the model
+ # does not have a matching attribute, the key/value pair is assigned as
+ # a stub return value using RSpec's mocking/stubbing framework.
+ #
+ # new_record? is overridden to return the result of id.nil? This means
+ # that by default new_record? will return false. If you explicitly set
+ # :id => nil, the object will behave as you would expect, and return
+ # true for new_record?
#
# == Examples
#
# stub_model(Person)
# stub_model(Person, :id => 37)
# stub_model(Person) do |person|
- # person.first_name = "David"
+ # model.first_name = "David"
# end
def stub_model(model_class, stubs = {})
id = @@model_id
@@ -70,16 +82,24 @@ module Spec
:id => id
}.merge(stubs)
returning model_class.new do |model|
- add_stubs(model, stubs)
+ model.id = stubs.delete(:id)
(class << model; self; end).class_eval do
def connection
raise IllegalDataAccessException.new("stubbed models are not allowed to access the database")
end
+ def new_record?
+ id.nil?
+ end
end
+ stubs.each do |k,v|
+ if model.has_attribute?(k)
+ model[k] = stubs.delete(k)
+ end
+ end
+ add_stubs(model, stubs)
yield model if block_given?
end
end
-
#--
# TODO - Shouldn't this just be an extension of stub! ??
# - object.stub!(:method => return_value, :method2 => return_value2, :etc => etc) |
| |   |
| 6 | 6 | stub_model(MockableModel).id.should be >= 1000 |
| 7 | 7 | end |
| 8 | 8 | |
| 9 | it "should say it is not a new record by default" do |
| 10 | stub_model(MockableModel).should_not be_new_record |
| 11 | end |
| 12 | |
| 9 | 13 | it "should accept a stub id" do |
| 10 | | stub_model(MockableModel, :id => 3).id.should == 3 |
| 14 | stub_model(MockableModel, :id => 37).id.should == 37 |
| 15 | end |
| 16 | |
| 17 | it "should say it is a new record when id is set to nil" do |
| 18 | stub_model(MockableModel, :id => nil).should be_new_record |
| 11 | 19 | end |
| 12 | 20 | |
| 13 | 21 | it "should accept a stub anything" do |
| 14 | 22 | stub_model(MockableModel, :foo => "bar").foo.should == "bar" |
| 15 | 23 | end |
| 16 | 24 | |
| 25 | it "should accept a stub for save" do |
| 26 | stub_model(MockableModel, :save => false).save.should be(false) |
| 27 | end |
| 28 | |
| 17 | 29 | it "should raise when hitting the db" do |
| 18 | 30 | lambda do |
| 19 | 31 | stub_model(MockableModel).save |
| toggle raw diff |
--- a/rspec_on_rails/spec/rails/mocks/stub_model_spec.rb
+++ b/rspec_on_rails/spec/rails/mocks/stub_model_spec.rb
@@ -6,14 +6,26 @@ describe "stub_model" do
stub_model(MockableModel).id.should be >= 1000
end
+ it "should say it is not a new record by default" do
+ stub_model(MockableModel).should_not be_new_record
+ end
+
it "should accept a stub id" do
- stub_model(MockableModel, :id => 3).id.should == 3
+ stub_model(MockableModel, :id => 37).id.should == 37
+ end
+
+ it "should say it is a new record when id is set to nil" do
+ stub_model(MockableModel, :id => nil).should be_new_record
end
it "should accept a stub anything" do
stub_model(MockableModel, :foo => "bar").foo.should == "bar"
end
+ it "should accept a stub for save" do
+ stub_model(MockableModel, :save => false).save.should be(false)
+ end
+
it "should raise when hitting the db" do
lambda do
stub_model(MockableModel).save |