rogue-objects 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/Gemfile.lock +1 -1
- data/README.md +77 -3
- data/lib/rogue/version.rb +1 -1
- data/rogue-objects.gemspec +3 -3
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42ae355b7cf52f90793cc7d7bc8591c21e6b57e9bbe04f643af50c26d62a9ca8
|
4
|
+
data.tar.gz: ef05fafb0fa0087dcd7cabbfa05020b71a88c6d315043ed71aac6b45d579c315
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85fa83300efd8d911b5f6cc928509123f25711d9fa3e10525e05d5a6b33683de064f61daf45ba820ab6de599cc26f1357da18bb8f4592126c3d1f97d66467171
|
7
|
+
data.tar.gz: f2748be9fa753f8a995198aff59e518f58a562c0a01c9203f2b699517535b0d51b062fbd0557d2cf5b0f3fc8e18819e6e7c58ce766cfc51a0df61e44a3dfd968
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -2,14 +2,15 @@
|
|
2
2
|
|
3
3
|
Rogue-Objects is a set of utilities to help developers write focused unit tests. It includes
|
4
4
|
a Rogue-Object component which is a dynamic object that can be created with properties & functions
|
5
|
-
that can be accessed via dot notation.
|
5
|
+
that can be accessed via dot notation. It also includes various helper functions to to make MiniTest
|
6
|
+
mock objects slightly simpler.
|
6
7
|
|
7
8
|
## Installation
|
8
9
|
|
9
10
|
Add this line to your application's Gemfile:
|
10
11
|
|
11
12
|
```ruby
|
12
|
-
gem 'rogue'
|
13
|
+
gem 'rogue-objects'
|
13
14
|
```
|
14
15
|
|
15
16
|
And then execute:
|
@@ -18,10 +19,11 @@ And then execute:
|
|
18
19
|
|
19
20
|
Or install it yourself as:
|
20
21
|
|
21
|
-
$ gem install rogue
|
22
|
+
$ gem install rogue-objects
|
22
23
|
|
23
24
|
## Usage
|
24
25
|
|
26
|
+
### Rogue-Object use
|
25
27
|
Scenario:
|
26
28
|
You need to test a DuckHunter which requires an object that looks like a duck and quacks like a duck
|
27
29
|
but you don't want to create an actual duck. Rogue-Objects give you an `obj` expression you can use
|
@@ -51,6 +53,78 @@ end
|
|
51
53
|
This hunter can be supplied with our duck without the need to load the actual Duck class, formally create
|
52
54
|
a Duck class substitution class, or use too much noise code from mock frameworks.
|
53
55
|
|
56
|
+
### Minitest Mocking use
|
57
|
+
Mini test mocks allow you to create objects that expect calls. However your code can get noisy when the object
|
58
|
+
you're testing makes several chained method calls. Consider the following irresponsible teacher that only
|
59
|
+
teaches the first student in class:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
class IrresponsibleTeacher
|
63
|
+
def teach
|
64
|
+
@students.first.find_first_lesson.learn(self)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
```
|
68
|
+
If we wanted to use mocks we would have to mock the students object and get it to return a mock student.
|
69
|
+
We would have to tell this mocked student to return a mocked first lesson then tell that mocked lesson
|
70
|
+
to expect a call to its learn method.
|
71
|
+
```ruby
|
72
|
+
irresponsible_teacher = IrresponsibleTeacher.new
|
73
|
+
mock_students = ::Minitest::Mock.new
|
74
|
+
mock_first_student = ::Minitest::Mock.new
|
75
|
+
mock_lesson = ::Minitest::Mock.new
|
76
|
+
mock_students.expect(:first,mock_first_student)
|
77
|
+
mock_first_student.expect(:find_first_lesson,mock_lesson)
|
78
|
+
mock_lesson.expect(:learn,nil,[irresponsible_teacher])
|
79
|
+
```
|
80
|
+
This code can be simplified by using the `::Rogue::Support::MockMethods.expect_chained_call` method over
|
81
|
+
the mock.
|
82
|
+
```ruby
|
83
|
+
include ::Rogue::Support::MockMethods
|
84
|
+
irresponsible_teacher = IrresponsibleTeacher.new
|
85
|
+
mock_students = ::Minitest::Mock.new
|
86
|
+
expect_chained_call(mock_students, 'first.find_first_lesson.learn', nil, irresponsible_teacher)
|
87
|
+
```
|
88
|
+
|
89
|
+
In each step of this chained method call our mock will return itself with an expectation to receive the
|
90
|
+
next call in the chain.
|
91
|
+
|
92
|
+
Mocking in Minitest (as well as other mock object frameworks) reverses the Given/When/Then pattern
|
93
|
+
in your code. That is, you have to set your assertions/expectations up front (the then part), followed
|
94
|
+
by the action you want to test. This can make code slightly harder to follow because the thing you want
|
95
|
+
to test can get lost beneath the mock setup. Consider the following scenario.
|
96
|
+
We have an order processor which should get the cost and ship our delicate item to San Fransisco.
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
mock_order = ::Minitest::Mock.new
|
100
|
+
mock_order.expect(:total_cost,29.99)
|
101
|
+
mock_order.expect(:special_instructions,"handle with care")
|
102
|
+
mock_order.expect(:ship, nil, "San Fransisco")
|
103
|
+
@order_processor.process(mock_order)
|
104
|
+
mock_order.verify
|
105
|
+
```
|
106
|
+
Here we are starting with the given, then setting the expectations, and finally taking our action
|
107
|
+
Following Given/When/Then you woud want to code the expectations after you take the action
|
108
|
+
of processing the order. With `::Rogue::Support::MockMethods.expect_chained_call` we can reverse
|
109
|
+
the order of code conceptually but still maintain the order of operations semantically. This is
|
110
|
+
supported via a bit of syntax sugar as follows:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
with_new_mock { |mock_order| @order_processor.process(mock_order) }
|
114
|
+
.verify_the_mock do |mock_order|
|
115
|
+
mock_order.expect(:total_cost,29.99)
|
116
|
+
mock_order.expect(:special_instructions,"handle with care")
|
117
|
+
mock_order.expect(:ship, nil, "San Fransisco")
|
118
|
+
end
|
119
|
+
```
|
120
|
+
|
121
|
+
In the above example we make use of blocks to group the sections and order them
|
122
|
+
conceptually while the semantic order of execution is preserved. Internally the
|
123
|
+
Rogue-Objects API will create a mock object and execute the `verify_the_mock`
|
124
|
+
block with this new mock first. This allows all expectations to be set initially.
|
125
|
+
Control is then delegated to the `with_new_mock` block with this same internal
|
126
|
+
mock. The mock is automatically verified after the `with_new_mock` block completes.
|
127
|
+
|
54
128
|
## Development
|
55
129
|
|
56
130
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/rogue/version.rb
CHANGED
data/rogue-objects.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
|
|
6
6
|
spec.name = "rogue-objects"
|
7
7
|
spec.version = Rogue::VERSION
|
8
8
|
spec.authors = ["Clifton Craig"]
|
9
|
-
spec.email = ["
|
9
|
+
spec.email = ["c.craig@samsung.com"]
|
10
10
|
|
11
11
|
spec.summary = "A gem to augment unit testing"
|
12
12
|
spec.description = "Ruby MiniTest utilities"
|
@@ -15,8 +15,8 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
16
16
|
|
17
17
|
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
-
spec.metadata["source_code_uri"] = "https://github.com/
|
19
|
-
spec.metadata["changelog_uri"] = "https://github.com/
|
18
|
+
spec.metadata["source_code_uri"] = "https://github.com/adgear/rogue-objects"
|
19
|
+
spec.metadata["changelog_uri"] = "https://github.com/adgear/rogue-objects/CHANGELOG.md"
|
20
20
|
|
21
21
|
# Specify which files should be added to the gem when it is released.
|
22
22
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
metadata
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rogue-objects
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Clifton Craig
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-02-
|
11
|
+
date: 2021-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Ruby MiniTest utilities
|
14
14
|
email:
|
15
|
-
-
|
15
|
+
- c.craig@samsung.com
|
16
16
|
executables: []
|
17
17
|
extensions: []
|
18
18
|
extra_rdoc_files: []
|
@@ -36,8 +36,8 @@ licenses:
|
|
36
36
|
- MIT
|
37
37
|
metadata:
|
38
38
|
homepage_uri: https://github.com/cliff76/rogue-objects
|
39
|
-
source_code_uri: https://github.com/
|
40
|
-
changelog_uri: https://github.com/
|
39
|
+
source_code_uri: https://github.com/adgear/rogue-objects
|
40
|
+
changelog_uri: https://github.com/adgear/rogue-objects/CHANGELOG.md
|
41
41
|
post_install_message:
|
42
42
|
rdoc_options: []
|
43
43
|
require_paths:
|