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

Entity return values and contracts #64

Open
tpendragon opened this issue Jan 1, 2015 · 2 comments
Open

Entity return values and contracts #64

tpendragon opened this issue Jan 1, 2015 · 2 comments

Comments

@tpendragon
Copy link
Contributor

So I have service objects which have methods that return new entities - builders are a good example. However, if I stub out that service object to return a fake of the class it's supposed to return (or even a blank instance of the same class!) when I verify the contract it says it failed.

I can sort of understand why - but I'm concerned that forcing me to return nicely equivalent entities will result in complicated collaboration testing.

@psyho
Copy link
Owner

psyho commented Jan 2, 2015

This is a problem with contract tests that I'm aware of. Returning "real looking" data is sometimes problematic, because it leads to "noisy" tests (a lot of test body is responsible for creating that data). This problem is relatively easy to work around if you use "fixtures" (named helpers for returning built objects).

Sometimes, like you mentioned, the equality rules for the real looking data mean that two objects built in the exact same way are not equal (like User.new != User.new if User is an ActiveRecord model), which complicates things even further.

A solution that might work (but I haven't implemented in Bogus yet), is having some sort of placeholder.

I'd imagine the API looking like this:

stub(FooBuilder).build(any_args) { instance_of(:foo) }

This would return the same thing as fake(:foo), but with overwritten equality rules, so that it would be the same as any instance of Foo (or whatever class is configured to be copied by fake(:foo)).

What do you think, would that fix the problem you're having? Do you have any other ideas how this might be solved?

@tpendragon
Copy link
Contributor Author

Thanks for looking into this. I think the case where I return an object is moderately rare (except maybe in the case of class calls, and there's no support for simultaneous class/instance contract verification) and your API would probably work for that case.

I ran into something similar yesterday though. If I put an expectation on a dependency (service1) to be called with a second dependency (user) as an argument, the contract for service1 can't ever be fulfilled. I write a test for service1 such that if given a mock user (which is a double of the same class, with the same stubs) it returns an appropriate value - however, two fakes are never equivalent unless they have the same object ID (as far as I can tell), and so the argument signatures don't match. It would probably be a good idea for fake1 to equal fake2 if all their stubbed interactions and class matches.

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