Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature request - support stubbing with *multiple* hardcoded values #11

Closed
beluchin opened this issue Jan 2, 2019 · 4 comments
Closed

Comments

@beluchin
Copy link

beluchin commented Jan 2, 2019

Hello - great little library!

I was wondering whether you would be open to enhancing spy.core/stub to support multiple hardcoded values. For example:

(testing "multiple hardcoded values"
    (let [f (spy.core/stub 42 24)]
      (is (= 42 (f))
      ;; 24 from here on out
      (is (= 24 (f))
      (is (= 24 (f))
      (is (= 24 (f))))

If so, I could give it a shot and submit a pull request for you.

Interested?

@alexanderjamesking
Copy link
Owner

alexanderjamesking commented Jan 3, 2019

Hi @beluchin

Interesting idea, I can see the value in being able to supply a sequence of responses to a stub but perhaps it would be better to default to nil when the sequence of responses has been exhausted:

(testing "multiple hardcoded values"
    (let [f (spy.core/stub 42 24)]
      (is (= 42 (f))
      (is (= 24 (f))
      (is (nil? (f)))))

Another option is to throw an exception once the list of responses is exhausted instead of returning nil, or for this to be a different fn entirely (but then I'm struggling to think of a name for it).

You can also achieve the same thing by using spy.core/spy and providing your own function that serves different responses:

(let [responses (atom [42 24])
           responder (fn []
                       (let [response (first @responses)]
                         (swap! responses rest)
                         response))
           f (spy/spy responder)]
       (is (= 42 (f)))
       (is (= 24 (f)))
       (is (nil? (f))))

ps. If you want to modify spy.core/stub to work this way when accepting multiple arguments I'd happily accept a PR, or I can take a look at it myself when I get time.

Thank you for the positive comments and for using spy!

@beluchin
Copy link
Author

beluchin commented Jan 3, 2019

perhaps it would be better to default to nil when the sequence of responses has been exhausted

such behavior would be inconsistent with the existing semantics of spy.core/stub with one argument which returns the argument constantly.

You can also achieve the same thing by using spy.core/spy and providing your own function that serves different responses

Agree. However, I see a gain in readability afforded by the spy.core/stub semantics which, in my experience, are required often enough.

@alexanderjamesking
Copy link
Owner

The reason I'm unsure is that it adds behaviour to spy.core/stub that isn't obvious, at the moment it's simple as it just returns the same value constantly, but as soon as it starts to return different values based on either the arguments passed, or the number of times it is called, then it's really a mock not a stub.

I think there is room in this library for a namespace providing helper functions for common patterns (such as returning a value on nth call, throwing an exception on nth call...) but I need to spend some time thinking about first.

@beluchin
Copy link
Author

beluchin commented Jan 3, 2019

In that light, I see two clear concepts here related to wrapping an original function: mocks and spies. They both allow interaction verifications and:
mocks: do not call the original function. The original function's implementation is replaced.
spies: call the original function.

I don't see what a notion of stubs adds to that picture.

From the above follows that mocks need to be provided the function to replace the original function's implementation with. In that case the library of helpers would make sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants