faraday-hot_mock 0.4.1 → 0.5.0
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/README.md +37 -2
- data/lib/faraday/hot_mock/adapter.rb +24 -1
- data/lib/faraday/hot_mock/version.rb +1 -1
- data/lib/faraday/hot_mock.rb +14 -4
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d42875d59eb57c21511d1c8edb287415cfae818f0a5af8b3be38f06086c8920f
|
|
4
|
+
data.tar.gz: 22551de3ae9e35709702c762880abbf797407f4e95e4f84a53e6bc3f930c4337
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8bf83f23c923e2459e5cc1d50005959df3f9113cb029c2cdf28f6a28967f67f2c00003d1ee2f4fcd25a00e2787665ea73056759137266f3e22de604c8cda606e
|
|
7
|
+
data.tar.gz: 30dbdcccbb2bad3aa706614b4b1b759ec18e7e995e422cf8fa6beb568034940732cce587a345e2874fb2afd68d60e1f308817ce815defdcadb95bed016e6ff5a
|
data/README.md
CHANGED
|
@@ -81,14 +81,49 @@ It can also be a terrible idea if your mocks are designed for your specific need
|
|
|
81
81
|
|
|
82
82
|
It's up to you and your team what makes sense.
|
|
83
83
|
|
|
84
|
-
In most cases, it makes sense to check in the mocks for
|
|
84
|
+
In most cases, it makes sense to not check in the mocks for any environment, so in most cases you should add to your `.gitignore`:
|
|
85
85
|
|
|
86
86
|
```
|
|
87
87
|
# Ignore Faraday HotMocks except in test env
|
|
88
88
|
lib/faraday/mocks/**
|
|
89
|
-
!lib/faraday/mocks/test
|
|
90
89
|
```
|
|
91
90
|
|
|
91
|
+
### Scenarios
|
|
92
|
+
|
|
93
|
+
You can use directories to conditionally group mocks. For example, you might want a "success" scenario and an "failure" scenario.
|
|
94
|
+
|
|
95
|
+
To do that, simply create the `/scenarios/success` and `/scenarios/failure` subdirectories within `lib/faraday/mocks/#{Rails.env}/`, and place the appropriate mock files in each, probably with the same endpoints but with different responses.
|
|
96
|
+
|
|
97
|
+
Then call `Faraday::HotMock.scenario = :success` or `Faraday::HotMock.scenario = :failure` to switch between them.
|
|
98
|
+
|
|
99
|
+
When a scenario is active, only mocks in that scenario directory will be considered. If no matching mock is found in that scenario, then the real request will be made.
|
|
100
|
+
|
|
101
|
+
To use the mocks not in the `scenarios` directory again, simply set `Faraday::HotMock.scenario = nil`.
|
|
102
|
+
|
|
103
|
+
### Testing
|
|
104
|
+
|
|
105
|
+
In tests, you can certainly use a mocking library of choice. In many cases, that might be easier. This is because Faraday::HotMock is built for quick iteration using runtime-loaded YAML files, which isn't needed in tests.
|
|
106
|
+
|
|
107
|
+
If instead you want to use Faraday::HotMock, you can create mocked responses by hand, or use `Faraday::HotMock.mock!` to define mocks in a very similar way to other mocking libraries (similar to `stub_request` in WebMock, for example).
|
|
108
|
+
|
|
109
|
+
The most basic setup would be:
|
|
110
|
+
|
|
111
|
+
- Call `Faraday::HotMock.enable!` in your test setup
|
|
112
|
+
- Call `Faraday::HotMock.disable!` in your test teardown
|
|
113
|
+
- In a given test/spec or in a method, call `Faraday::HotMock.mock!(method: [method], url_pattern: [url], status: [status code], headers: [headers hash], body: [body])` to define a mock for that test/spec.
|
|
114
|
+
- Remove the mock file in teardown by referencing `Faraday::HotMock.hot_mock_file` (via `File.delete` or `FileUtils.rm`) since you probably don't want them to persist between tests
|
|
115
|
+
|
|
116
|
+
If you use scenarios, then you can do a bit less:
|
|
117
|
+
|
|
118
|
+
- Call `Faraday::HotMock.enable!` in your test setup
|
|
119
|
+
- Call `Faraday::HotMock.disable!` in your test teardown
|
|
120
|
+
- Call `Faraday::HotMock.scenario = :your_scenario_name` in a given test/spec
|
|
121
|
+
- Call `Faraday::HotMock.scenario = nil` in your test teardown if using scenarios
|
|
122
|
+
|
|
123
|
+
Overall, this may be a bit more work but it has the advantage that you can use the same mocking mechanism in both development and testing, which can reduce surprises when moving code between the two.
|
|
124
|
+
|
|
125
|
+
Small bonus: if you use `Faraday::HotMock` everywhere, you can remove the dependency for whichever mocking library/libraries you were using before.
|
|
126
|
+
|
|
92
127
|
### Convenience Methods
|
|
93
128
|
|
|
94
129
|
You can enable or disable mocking programmatically with these methods:
|
|
@@ -23,11 +23,34 @@ module Faraday
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
if Faraday::HotMock.enabled? && (mock = Faraday::HotMock.mocked?(method: env.method, url: env.url))
|
|
26
|
-
|
|
26
|
+
interpolate(mock, env) if mock_interpolated?(mock)
|
|
27
|
+
|
|
28
|
+
save_response(
|
|
29
|
+
env,
|
|
30
|
+
mock["status"] || 200,
|
|
31
|
+
mock["body"] || "",
|
|
32
|
+
(mock["headers"] || {}).merge("x-hot-mocked" => "true")
|
|
33
|
+
)
|
|
27
34
|
else
|
|
28
35
|
@fallback_adapter.new(@app, @options).call(env)
|
|
29
36
|
end
|
|
30
37
|
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def mock_interpolated?(mock)
|
|
42
|
+
mock.key?("interpolate") && mock["body"].is_a?(Hash)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def interpolate(mock, env)
|
|
46
|
+
request_hash = JSON.parse(env.request_body) rescue {}
|
|
47
|
+
|
|
48
|
+
interpolated_hash = mock["interpolate"].transform_values do |v|
|
|
49
|
+
v = request_hash[v]
|
|
50
|
+
end.compact
|
|
51
|
+
|
|
52
|
+
mock["body"].merge!(interpolated_hash || {})
|
|
53
|
+
end
|
|
31
54
|
end
|
|
32
55
|
end
|
|
33
56
|
end
|
data/lib/faraday/hot_mock.rb
CHANGED
|
@@ -7,6 +7,8 @@ module Faraday
|
|
|
7
7
|
module HotMock
|
|
8
8
|
extend self
|
|
9
9
|
|
|
10
|
+
attr_accessor :scenario
|
|
11
|
+
|
|
10
12
|
def disable!
|
|
11
13
|
FileUtils.rm_f(hot_mocking_file)
|
|
12
14
|
end
|
|
@@ -31,7 +33,7 @@ module Faraday
|
|
|
31
33
|
end
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
def
|
|
36
|
+
def delete(method:, url:)
|
|
35
37
|
return unless File.exist?(hot_mock_file)
|
|
36
38
|
|
|
37
39
|
mocks = YAML.load_file(hot_mock_file) || []
|
|
@@ -79,7 +81,7 @@ module Faraday
|
|
|
79
81
|
"method" => method.to_s.upcase,
|
|
80
82
|
"url_pattern" => url,
|
|
81
83
|
"status" => response.status,
|
|
82
|
-
"headers" => response.headers.to_h.merge("x-
|
|
84
|
+
"headers" => response.headers.to_h.merge("x-hot-mock-recorded-at" => Time.now.utc.iso8601),
|
|
83
85
|
"body" => response.body
|
|
84
86
|
}
|
|
85
87
|
|
|
@@ -103,7 +105,7 @@ module Faraday
|
|
|
103
105
|
"method" => method.to_s.upcase,
|
|
104
106
|
"url_pattern" => url,
|
|
105
107
|
"status" => response.status,
|
|
106
|
-
"headers" => response.headers.to_h.merge("x-
|
|
108
|
+
"headers" => response.headers.to_h.merge("x-hot-mock-recorded-at" => Time.now.utc.iso8601, "x-hot-mock" => "true"),
|
|
107
109
|
"body" => response.body
|
|
108
110
|
}
|
|
109
111
|
|
|
@@ -116,6 +118,10 @@ module Faraday
|
|
|
116
118
|
Rails.root.join "lib/faraday/mocks/#{Rails.env}"
|
|
117
119
|
end
|
|
118
120
|
|
|
121
|
+
def scenario_dir
|
|
122
|
+
Rails.root.join "lib/faraday/mocks/#{Rails.env}/scenarios"
|
|
123
|
+
end
|
|
124
|
+
|
|
119
125
|
def hot_mocking_file
|
|
120
126
|
Rails.root.join "tmp/mocking-#{Rails.env}.txt"
|
|
121
127
|
end
|
|
@@ -138,7 +144,11 @@ module Faraday
|
|
|
138
144
|
end
|
|
139
145
|
|
|
140
146
|
def all_hot_mock_files
|
|
141
|
-
|
|
147
|
+
if scenario
|
|
148
|
+
Dir.glob(File.join(hot_mock_dir, "scenarios", scenario.to_s, "**", "*.{yml,yaml}"))
|
|
149
|
+
else
|
|
150
|
+
Dir.glob(File.join(hot_mock_dir, "**", "*.{yml,yaml}")).reject { |path| path.include?("/scenarios/") }
|
|
151
|
+
end
|
|
142
152
|
end
|
|
143
153
|
end
|
|
144
154
|
end
|