rspec-rails-mocha 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +22 -0
- data/Rakefile +5 -0
- data/lib/rspec-rails-mocha.rb +7 -0
- data/lib/rspec/rails/mocha.rb +139 -0
- data/spec/mocha_spec.rb +86 -0
- metadata +102 -0
data/README.markdown
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
rspec-rails Mocha extension
|
2
|
+
===========================
|
3
|
+
|
4
|
+
Functionality of `mock_model` and `stub_model` from rspec-rails for those using Mocha.
|
5
|
+
|
6
|
+
Installation:
|
7
|
+
|
8
|
+
# Gemfile
|
9
|
+
group :test do
|
10
|
+
gem 'rspec-rails-mocha'
|
11
|
+
end
|
12
|
+
|
13
|
+
Usage:
|
14
|
+
|
15
|
+
describe "Mocha plugin" do
|
16
|
+
it "#mock_model should use given ID" do
|
17
|
+
person = mock_model(Person, :id => 66)
|
18
|
+
|
19
|
+
person.should_not be_new_record
|
20
|
+
person.id.should == 66
|
21
|
+
end
|
22
|
+
end
|
data/Rakefile
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
# copied from rspec-rails v1.3 and tweaked to work as expected with Mocha
|
2
|
+
# TODO: update to reflect the API of rspec-rails 2.0
|
3
|
+
module Spec
|
4
|
+
module Rails
|
5
|
+
unless defined?(IllegalDataAccessException)
|
6
|
+
class IllegalDataAccessException < StandardError; end
|
7
|
+
end
|
8
|
+
|
9
|
+
module Mocha
|
10
|
+
# Creates a mock object instance for a +model_class+ with common
|
11
|
+
# methods stubbed out. Additional methods may be easily stubbed (via
|
12
|
+
# add_stubs) if +stubs+ is passed.
|
13
|
+
def mock_model(model_class, options_and_stubs = {})
|
14
|
+
id = options_and_stubs[:id] || next_id
|
15
|
+
options_and_stubs = options_and_stubs.reverse_merge({
|
16
|
+
:id => id,
|
17
|
+
:to_param => id.to_s,
|
18
|
+
:new_record? => false,
|
19
|
+
:errors => stub("errors", :count => 0)
|
20
|
+
})
|
21
|
+
m = stub("#{model_class.name}_#{id}", options_and_stubs)
|
22
|
+
m.instance_eval <<-CODE
|
23
|
+
def as_new_record
|
24
|
+
self.stubs(:id).returns(nil)
|
25
|
+
self.stubs(:to_param).returns(nil)
|
26
|
+
self.stubs(:new_record?).returns(true)
|
27
|
+
self
|
28
|
+
end
|
29
|
+
def is_a?(other)
|
30
|
+
#{model_class}.ancestors.include?(other)
|
31
|
+
end
|
32
|
+
def kind_of?(other)
|
33
|
+
#{model_class}.ancestors.include?(other)
|
34
|
+
end
|
35
|
+
def instance_of?(other)
|
36
|
+
other == #{model_class}
|
37
|
+
end
|
38
|
+
def class
|
39
|
+
#{model_class}
|
40
|
+
end
|
41
|
+
CODE
|
42
|
+
yield m if block_given?
|
43
|
+
m
|
44
|
+
end
|
45
|
+
|
46
|
+
module ModelStubber
|
47
|
+
def connection
|
48
|
+
raise IllegalDataAccessException.new("stubbed models are not allowed to access the database")
|
49
|
+
end
|
50
|
+
def new_record?
|
51
|
+
id.nil?
|
52
|
+
end
|
53
|
+
def as_new_record
|
54
|
+
self.id = nil
|
55
|
+
self
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# :call-seq:
|
60
|
+
# stub_model(Model)
|
61
|
+
# stub_model(Model).as_new_record
|
62
|
+
# stub_model(Model, hash_of_stubs)
|
63
|
+
# stub_model(Model, instance_variable_name, hash_of_stubs)
|
64
|
+
#
|
65
|
+
# Creates an instance of +Model+ that is prohibited from accessing the
|
66
|
+
# database*. For each key in +hash_of_stubs+, if the model has a
|
67
|
+
# matching attribute (determined by asking it) are simply assigned the
|
68
|
+
# submitted values. If the model does not have a matching attribute, the
|
69
|
+
# key/value pair is assigned as a stub return value using RSpec's
|
70
|
+
# mocking/stubbing framework.
|
71
|
+
#
|
72
|
+
# <tt>new_record?</tt> is overridden to return the result of id.nil?
|
73
|
+
# This means that by default new_record? will return false. If you want
|
74
|
+
# the object to behave as a new record, sending it +as_new_record+ will
|
75
|
+
# set the id to nil. You can also explicitly set :id => nil, in which
|
76
|
+
# case new_record? will return true, but using +as_new_record+ makes the
|
77
|
+
# example a bit more descriptive.
|
78
|
+
#
|
79
|
+
# While you can use stub_model in any example (model, view, controller,
|
80
|
+
# helper), it is especially useful in view examples, which are
|
81
|
+
# inherently more state-based than interaction-based.
|
82
|
+
#
|
83
|
+
# == Database Independence
|
84
|
+
#
|
85
|
+
# +stub_model+ does not make your examples entirely
|
86
|
+
# database-independent. It does not stop the model class itself from
|
87
|
+
# loading up its columns from the database. It just prevents data access
|
88
|
+
# from the object itself. To completely decouple from the database, take
|
89
|
+
# a look at libraries like unit_record or NullDB.
|
90
|
+
#
|
91
|
+
# == Examples
|
92
|
+
#
|
93
|
+
# stub_model(Person)
|
94
|
+
# stub_model(Person).as_new_record
|
95
|
+
# stub_model(Person, :id => 37)
|
96
|
+
# stub_model(Person) do |person|
|
97
|
+
# person.first_name = "David"
|
98
|
+
# end
|
99
|
+
def stub_model(model_class, stubs={})
|
100
|
+
stubs = {:id => next_id}.merge(stubs)
|
101
|
+
model_class.new.tap do |model|
|
102
|
+
model.id = stubs.delete(:id)
|
103
|
+
model.extend ModelStubber
|
104
|
+
stubs.each do |k,v|
|
105
|
+
if model.has_attribute?(k)
|
106
|
+
model[k] = stubs.delete(k)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
model.stubs(stubs)
|
110
|
+
yield model if block_given?
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# DEPRECATED - use object.stubs(:method => value, :method2 => value)
|
115
|
+
#
|
116
|
+
# Stubs methods on +object+ (if +object+ is a symbol or string a new mock
|
117
|
+
# with that name will be created). +stubs+ is a Hash of +method=>value+
|
118
|
+
def add_stubs(object, stubs = {}) #:nodoc:
|
119
|
+
Kernel.warn <<-WARNING
|
120
|
+
DEPRECATION NOTICE: add_stubs is deprecated and will be removed
|
121
|
+
from a future version of rspec-rails. Use this instead:
|
122
|
+
|
123
|
+
object.stubs(:method => value, :method2 => value)
|
124
|
+
|
125
|
+
WARNING
|
126
|
+
object.stubs(stubs)
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
@@model_id = 1000
|
132
|
+
|
133
|
+
def next_id
|
134
|
+
@@model_id += 1
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
data/spec/mocha_spec.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spec/autorun'
|
2
|
+
require 'rspec-rails-mocha'
|
3
|
+
require 'active_support/core_ext'
|
4
|
+
|
5
|
+
class Person
|
6
|
+
attr_accessor :id, :name
|
7
|
+
|
8
|
+
def has_attribute?(attr)
|
9
|
+
respond_to?(attr)
|
10
|
+
end
|
11
|
+
|
12
|
+
def []=(attr, value)
|
13
|
+
self.send("#{attr}=", value)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Hacker < Person
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "rspec-rails Mocha plugin" do
|
21
|
+
|
22
|
+
share_examples_for "model" do
|
23
|
+
it "should be of correct class" do
|
24
|
+
model = create(Hacker)
|
25
|
+
|
26
|
+
model.is_a?(Person).should be_true
|
27
|
+
model.kind_of?(Person).should be_true
|
28
|
+
model.instance_of?(Person).should be_false
|
29
|
+
model.instance_of?(Hacker).should be_true
|
30
|
+
model.class.should == Hacker
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should auto-generate IDs" do
|
34
|
+
personA = create(Person)
|
35
|
+
personB = create(Person)
|
36
|
+
personA.id.should >= 1000
|
37
|
+
personB.id.should > personA.id
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should use given ID" do
|
41
|
+
person = create(Person, :id => 66)
|
42
|
+
person.id.should == 66
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should mock a record with properties" do
|
46
|
+
hacker = create(Hacker, :name => "Mislav", :skillz => 1337)
|
47
|
+
hacker.name.should == "Mislav"
|
48
|
+
hacker.skillz.should == 1337
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should not be new record" do
|
52
|
+
create(Person).should_not be_new_record
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should be new record when explicitly stated" do
|
56
|
+
create(Person).as_new_record.should be_new_record
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#mock_model" do
|
61
|
+
it_should_behave_like "model"
|
62
|
+
|
63
|
+
def create(*args)
|
64
|
+
mock_model(*args)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should have no errors" do
|
68
|
+
create(Person).errors.count.should == 0
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#stub_model" do
|
73
|
+
it_should_behave_like "model"
|
74
|
+
|
75
|
+
def create(*args)
|
76
|
+
stub_model(*args)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "can't connect" do
|
80
|
+
lambda {
|
81
|
+
create(Person).connection
|
82
|
+
}.should raise_error(Spec::Rails::IllegalDataAccessException)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rspec-rails-mocha
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 2
|
10
|
+
version: 0.2.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- "Mislav Marohni\xC4\x87"
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-02-20 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: mocha
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 43
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 9
|
33
|
+
- 8
|
34
|
+
version: 0.9.8
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rspec-rails
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 31
|
46
|
+
segments:
|
47
|
+
- 1
|
48
|
+
- 3
|
49
|
+
- 2
|
50
|
+
version: 1.3.2
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
53
|
+
description: Ports functionality of mock_model and stub_model from rspec-rails using Mocha.
|
54
|
+
email: mislav.marohnic@gmail.com
|
55
|
+
executables: []
|
56
|
+
|
57
|
+
extensions: []
|
58
|
+
|
59
|
+
extra_rdoc_files: []
|
60
|
+
|
61
|
+
files:
|
62
|
+
- Rakefile
|
63
|
+
- lib/rspec/rails/mocha.rb
|
64
|
+
- lib/rspec-rails-mocha.rb
|
65
|
+
- spec/mocha_spec.rb
|
66
|
+
- README.markdown
|
67
|
+
has_rdoc: false
|
68
|
+
homepage: http://github.com/mislav/rspec-rails-mocha
|
69
|
+
licenses: []
|
70
|
+
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
hash: 3
|
82
|
+
segments:
|
83
|
+
- 0
|
84
|
+
version: "0"
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
hash: 3
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
version: "0"
|
94
|
+
requirements: []
|
95
|
+
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 1.5.0
|
98
|
+
signing_key:
|
99
|
+
specification_version: 3
|
100
|
+
summary: mock_model and stub_model with Mocha
|
101
|
+
test_files: []
|
102
|
+
|