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

Error when using immutable method on dependency, then using beConstructedWith() in spec #1448

Open
toby-griffiths opened this issue Jun 23, 2023 · 3 comments

Comments

@toby-griffiths
Copy link

toby-griffiths commented Jun 23, 2023

I am configuring Symfony's immutable HttpClient in the constructor of a service. I have the spec set up to return a new instance of the client in the let() method, which works fine in spec that don't reconfigure the constructor.

However, if I attempt to reconfigure the constructor in an example then I get an error about the return type…

class ApiClientSpec extends ObjectBehavior
{
    public function let(
        HttpClientInterface $initialHttpClient,
        HttpClientInterface $httpClient,
        ResponseInterface $response,
    ): void {
        $this->beConstructedWith('https://api.co', $initialHttpClient);

        $initialHttpClient->withOptions(Argument::type('array'))->willReturn($httpClient);

        $initialHttpClient->request(Argument::in(['GET']), Argument::type('string'))->willReturn($response);

        $response->getContent()->willReturn('[]');
    }


    public function it_is_initializable(): void
    {
        $this->shouldHaveType(ApiClient::class);
    }


    public function it_should_provide_the_base_url_length(HttpClientInterface $initialHttpClient): void
    {
        $this->beConstructedWith('https://api.co', $initialHttpClient);

        $this
            ->getBaseUrlLength()
            ->shouldReturn(14);
    }
}

… results in …

[err:TypeError("Double\HttpClientInterface\HttpClientInterface\P3::withOptions(): Return value must be of type Double\HttpClientInterface\HttpClientInterface\P3, Double\HttpClientInterface\P1 returned")] has been thrown.

… however, if I inject the resulting client into the example, even if it's not used, it works just fine…

    // …

    public function it_should_provide_the_base_url_length(
        HttpClientInterface $initialHttpClient,
        // Keep this here, as without it the example fails with a return type error
        // @see https://github.com/phpspec/phpspec/issues/1448
        HttpClientInterface $httpClient,
    ): void {
        $this->beConstructedWith('https://api.co', $initialHttpClient);

        $this
            ->getBaseUrlLength()
            ->shouldReturn(14);
    }

Is this a known limitation?

@toby-griffiths
Copy link
Author

toby-griffiths commented Jun 23, 2023

Actually, I've just realised it doesn't matter whehter I update the constructor args in a example or not, it gives the same error. I this I may have been mislead by my assuption that the it_is_initializable() example would instantiate the object?!

So this example also gives the Return value must be of type Double\HttpClientInterface\P1, Double\HttpClientInterface\HttpClientInterface\P3 returned error as well…

    public function it_should_send_get_requests(
        HttpClientInterface $httpClient,
        ResponseInterface $response,
    ): void {
        $response->getContent()->willReturn('{"id": 123, "name": "Bob Bobbins"}');

        $this
            ->get('people/123')
            ->shouldReturn(['id' => 123, 'name' => 'Bob Bobbins']);

        $httpClient->request('GET', 'people/123')->shouldBeCalledOnce();
    }

@ciaranmcnulty
Copy link
Member

Yes there is some semi-complex logic around when an object is instantiated, it may not be if the only assertion is about its type

I don't think this is a known issue

@toby-griffiths
Copy link
Author

Ah, OK. Thanks @ciaranmcnulty. Would yo like me to leave this open for review then? I'm working OK by storing the initial collaborator instances in properties and using them in the examples.

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