-
Notifications
You must be signed in to change notification settings - Fork 7
Default "empty" values for types #150
Comments
I'm leaning towards the partial mock route. It offers consistency with the behaviour of user-defined types, while also provided a working object. I'm less convinced about the exceptions/errors though, could these just be full mocks like all other types? I would add that making the 'empty' value for |
Further to that, is there any reason to treat |
Is there a difference in making a |
Nope. I guess, regarding |
That was my logic with
They could. It's just that, since they all have constructors that require no arguments, you get a fully working exception "for free" that already has an integer code, string message etc.
Good point. Probably doesn't work for
I don't think this can be done. Unless you can think of a way to get the original spy out of the |
Yep, agreed. JSON encoding, etc is a good point.
Seems fair enough, so this would extend to all concrete, built-in throwable types? Is it worth bringing other built-in types back into the discussion (we dismissed the SPL collection types in an earlier discussion).
I hadn't considered this (obviously). It is possible to assign arbitrary properties to It's not pretty, but I do suspect getting a generator spy by default could be quite useful, especially in Recoil. |
Yes, probably. Perhaps some kind of guideline like, if it's built in, can be created with an empty constructor, and has no side effects, then partial mock it?
Yeah, it's probably possible right now from a technical standpoint. Not sure if I want to introduce another facade method for it. Let me think some more about that one. |
After writing some more extensive tests for this stuff, it turns out that in the majority of cases, a partial mock is not necessary. By this I mean that:
There were a few other edge cases, and the process highlighted some inbuilt classes that Phony is having trouble mocking currently (#151). |
@jmalloc re generators, I realized that spying on generators won't be a problem here. This should work fine: $spy = spy(function (): Generator {});
$generator = $spy();
$generator->send('x');
$spy->received('x'); // should pass But perhaps you meant stubbing the returned generator? There would be no way to do that at the moment. I'm not sure it really makes sense anyway, I can't think of a good use-case. |
Okay, so that example is bad. Firstly, you need a stub, not a spy. Secondly, the generator spies are working, but as it turns out, there's not much that can be verified on an empty generator anyway. It never receives anything because it doesn't yield, and of course it never produces anything, and we don't yet have a $stub = stub(eval('return function (): Generator {};'))->returns();
iterator_to_array($stub());
$stub->producedAll(); |
Can I get some input on what would be the best options for default "empty" values for some built-in types? These currently drive Default values for return types, but in future may also drive some auto-wiring of type-hinted function parameters.
Here's what Phony currently handles:
null
bool
false
int
0
float
.0
string
''
array
[]
stdClass
(object) []
callable
function () {}
Traversable
new EmptyIterator()
Iterator
new EmptyIterator()
Generator
(function () {return; yield;})()
<type>
mock(<type>)->mock()
I'm thinking that the
EmptyIterator
ones are a strange outlier here, in that you can't wrap them in a mock handle and verify their interactions. Perhaps they should be partial mocks? There's also a few in-built classes not catered for.Here's some changes I'm considering:
Traversable
partialMock('EmptyIterator')->mock()
Iterator
partialMock('EmptyIterator')->mock()
Exception
partialMock('Exception')->mock()
RuntimeException
etc.partialMock('RuntimeException')->mock()
Error
partialMock('Error')->mock()
AssertionError
etc.partialMock('AssertionError')->mock()
callable
spy()
Closure
function () {}
The text was updated successfully, but these errors were encountered: