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

Bad exception message returned #4

Closed
frosty22 opened this issue Mar 22, 2013 · 7 comments
Closed

Bad exception message returned #4

frosty22 opened this issue Mar 22, 2013 · 7 comments

Comments

@frosty22
Copy link

Hi,

I found bug in returned exception, when I have simple code:

        $obj = $mockista->create("Foo");
        $obj->expects("bar")->with(1)->once();
        $obj->bar(2);

I except message of exception:

Unexpected call in mock Foo::bar(), args: array (0 => 2)

but I get:

Expected method Foo::bar() should be called exactly once but not called at all.

But if I have same code, without checking calls count:

        $obj = $mockista->create("Foo");
        $obj->expects("bar")->with(1);
        $obj->bar(2);

returned message is correct!

@jasir
Copy link
Contributor

jasir commented Mar 22, 2013

Works for me, try to add this test:

public function test_issue_4() {
    $this->object->expects('bar')->with(1)->once();
    try {
        $this->object->bar(2);
        $this->object->assertExpectations();
    } catch (\Mockista\MockException $e) {
        $this->assertEquals("Unexpected call in mock unnammed::bar(), args: array (\n  0 => 2,\n)", $e->getMessage());
        return;
    }
    $this->fail('No exception thrown');
}

If you are able to write failing test, I would try to fix that.

@frosty22
Copy link
Author

So, I'm sorry it is error on my side ... I use your BaseTestCase sample, where Mockista\Registry is used and error is in "$this->mockista->assertExpectations()" call..

This crash - "Mockista\MockException: Expected method unnamed::bar() should be called exactly once but not called at all."

class MockerTest extends \Tester\TestCase
{

    /** @var \Mockista\Registry */
    protected $mockista;

    protected $object;


    protected function setUp()
    {
        $this->mockista = new \Mockista\Registry();
    }

    protected function tearDown()
    {
        $this->mockista->assertExpectations(); // When I comment this, test is correct!
    }


    public function testIssue4() {
        $this->object = $this->mockista->create();
        $this->object->expects('bar')->with(1)->once();
        try {
            $this->object->bar(2);
            $this->object->assertExpectations();
        } catch (\Mockista\MockException $e) {
            Assert::equal("Unexpected call in mock unnammed::bar(), args: array (\n  0 => 2,\n)", $e->getMessage());
            return;
        }
        $this->fail('No exception thrown');
    }


}

@frosty22
Copy link
Author

So it's really problem in Nette/Tester, I still don't know why and I suppose you don't use it. But in Nette/Tester is problem in TestCase (base class of all tests), in this method of TestCase:

    /**
     * Runs the single test.
     * @return void
     */
    public function runTest($name, array $args = array())
    {
        $this->setUp();
        try {
            call_user_func_array(array($this, $name), $args);
        } catch (\Exception $e) {
        }
        $this->tearDown();
        if (isset($e)) {
            throw $e;
        }
    }

This cause that is returned invalid exception: "Expected method unnamed::bar() should be called exactly once but not called at all."

But when I move calling tearDown method inside try/catch:

    /**
     * Runs the single test.
     * @return void
     */
    public function runTest($name, array $args = array())
    {
        $this->setUp();
        try {
            call_user_func_array(array($this, $name), $args);
            $this->tearDown();
        } catch (\Exception $e) {
        }

        if (isset($e)) {
            throw $e;
        }
    }

It throw correct exception ... it's magic :)

@jasir
Copy link
Contributor

jasir commented Mar 23, 2013

It seems that problem is that assertExpectations is called twice - first call "resets" the previous calls, hence this message.

@janmarek
Copy link
Owner

If you call assertExpectations in tearDown method, you don't have to call it in your tests. It's called automatically for you.

@frosty22
Copy link
Author

I'm sorry, I placed bad sample code here. When I remove call "assertExpectations" in test's method, it still throw bad exception. For test I dumped mock in assertExpectations and it's really call only once, so there isn't problem. But problem really will be in implements with Nette/Tester.

@frosty22
Copy link
Author

Heureka! I found error, when method "bar" is called, it throw correct Exception with invalid arguments. But this exception is catch in "runTest" method. After it is call tearDown method and throw Exception with invalid count of calls, which isn't catch.

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

3 participants