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

Mocking a class without a mocked method that would normally return a promise causes the loop to stop without resolving the test #19

Closed
Nessworthy opened this issue Feb 8, 2021 · 2 comments

Comments

@Nessworthy
Copy link

For example:

<?php

use Amp\PHPUnit\AsyncTestCase;
use Amp\Success;
use Generator;

class MockedClass {
    public function doSomething(): Promise {
        return new Success('Some Value');
    }
}

class TestedClass {

    private MockedClass $mockedClass;

    public function __construct(MockedClass $mockedClass) {
        $this->mockedClass = $mockedClass;
    }

    public function performAction(): Promise
    {
        // Not the greatest example..
        return new Success( yield $this->mockedClass->doSomething() );
    }
}

class TestedClassTest extends AsyncTestCase {
    public function testPerformAction() {
        $mockedClass = $this->createMock(MockedClass::CLASS);
        $testedClass = new TestedClass($mockedClass);

        yield $testedClass->performAction();

        $this->assertEquals(1, 1);  // Is never reached.
    }
}

Causes: Loop stopped without resolving promise or coroutine returned from test method

If you define the method mock which is yielded inside TestedClass to return a promise, it works.

Caused a fair bit of confusion writing tests, wouldn't mind an easier to understand error message if possible!

@Nessworthy Nessworthy changed the title Mocking a class without a mocked method that would normally return a promise causes the loop to stop without resolving the promise. Mocking a class without a mocked method that would normally return a promise causes the loop to stop without resolving the test. Feb 8, 2021
@Nessworthy Nessworthy changed the title Mocking a class without a mocked method that would normally return a promise causes the loop to stop without resolving the test. Mocking a class without a mocked method that would normally return a promise causes the loop to stop without resolving the test Feb 8, 2021
@remorhaz
Copy link
Contributor

I've noticed this problem, too, but I don't have any idea of how it could be solved. The auto-mocked promise is never resolved for obvious reasons; the desired behavior would be probably to auto-return Amp\Success(<auto-mocked "real" type>). But here we face two problems:

  • How to extend the behavior of standard PHPUnit mock generator?
  • How to detect "real" type of a function?

@kelunik
Copy link
Member

kelunik commented Dec 3, 2021

Promises will be much less common in Amp v3, so it's hopefully no longer that relevant then.

@kelunik kelunik closed this as completed Dec 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants