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

Use reflection for mocked objects injection #4

Open
fesor opened this issue Mar 18, 2015 · 6 comments
Open

Use reflection for mocked objects injection #4

fesor opened this issue Mar 18, 2015 · 6 comments

Comments

@fesor
Copy link

fesor commented Mar 18, 2015

PhpSpec has it's great sugar for injection mocked objects. Is it possible to implement such thing in Peridot?

For example

<?php
describe('Bird', function() {

    beforeEach(function(Wings $wings) {
        $this->$bird = new Bird($wings);
    });

    it('should fly', function(Wings $wings) {
        $wings->swing()->shouldBeCalled();
        $this->bird->fly();
    });
});
@fesor
Copy link
Author

fesor commented Mar 18, 2015

Duplicate of #1.

@fesor fesor changed the title Use reflection for injection mocks Use reflection for mocked objects injection Mar 18, 2015
@brianium
Copy link
Member

I was waiting for someone else to take interest in this :) As of Peridot 1.15.0 it is possible for plugins to provide arguments to spec functions - so we could pass a prophecy object as an argument.

I think the complexity would come from the fact that the result of prophesize is an instance of ObjectProphecy - and I don't think that can be an instance of Wing. PhpSpec does a lot of work to make this happen, and though cool, it is very slow. I wonder if we could get around it with some sort of simple proxy object. I will investigate some options.

@fesor
Copy link
Author

fesor commented Mar 18, 2015

Prophet will return ObjectProphecy without doubler only if mocking class/interface doesn't exists. If class exists, you can get doubled object with reveal() method and inject it into callback arguments list. Need to check this to be sure.

@brianium
Copy link
Member

I believe you are correct, but the double will not have access to spies or method prophecies correct? The example above would not be possible. $wing would not have access to ->shouldBeCalled() - unless I am missing something?

@fesor
Copy link
Author

fesor commented Mar 18, 2015

Yes, you are right... The only possible way to call 'willReturn' is

function (Wings $wings) {
    $wings->getProphet()->swing()->willReturn('fly like an eagle');
}

Or...

<?php
describe('Bird', function() {

    beforeEach(function(Wings $wings) {
        // $wings is actually ObjectProphecy, or wrapped one
        $this->$bird = new Bird($wings->reveal()); // or ->unwrap() or ->getMock()
    });

    it('should fly', function(Wings $wings) {
        $wings->swing()->shouldBeCalled();
        $this->bird->fly();
    });
});

Unless testing class is wrapped with some proxy, it is very complicated to make this the same way as in phpspec.

@brianium
Copy link
Member

Challenge accepted! I'll spend a little time playing with a lightweight proxy implementation.

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