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

Method assertNotContains fails with string needle if array contains 0. #3940

Closed
kudashevs opened this issue Nov 11, 2019 · 4 comments
Closed

Comments

@kudashevs
Copy link

Q A
PHPUnit version 8.4.3
PHP version 7.2.0
Installation Method Composer / PHAR

Summary

I want to check that an array doesn't contain some string value.
If the array contains 0 as one of the values, assertNotContains fails assertion.

Current behavior

PHPUnit 8.4.3 by Sebastian Bergmann and contributors.

.F                                                                  2 / 2 (100%)

Time: 232 ms, Memory: 4.00 MB

There was 1 failure:

1) SomeTest::testTestWillFail
Failed asserting that an array does not contain 'test'.

E:\webserver\home\_development\www\php\sometest\tests\SomeTest.php:28

FAILURES!
Tests: 2, Assertions: 2, Failures: 1.

How to reproduce

Make fresh install of PHPUnit then execute this test:

use PHPUnit\Framework\TestCase;

class SomeTest extends TestCase
{

    public function testTestWillPass()
    {
        $arr = [
            'x' => 1,
            'y' => 1,
        ];

        $this->assertNotContains('test', $arr);
    }

    public function testTestWillFail()
    {
        $arr = [
            'x' => 1,
            'y' => 0,
        ];

        $this->assertNotContains('test', $arr);
    }
}

Was tested on 8, 7, 6 versions with same result.

Expected behavior

The second test should pass too, because array doesn't contain 'test' value.

@kudashevs kudashevs added the type/bug Something is broken label Nov 11, 2019
@kudashevs kudashevs changed the title Probably a bug in assertNotContains method The assertNotContains method fail if array contains 0 (probably a bug) Nov 11, 2019
@kudashevs kudashevs changed the title The assertNotContains method fail if array contains 0 (probably a bug) Method assertNotContains fails with string needle if array contains 0. Nov 11, 2019
@kudashevs
Copy link
Author

kudashevs commented Nov 11, 2019

This behavior doesn't depend on type of the array or its values. I've got the same result for indexed, associative arrays and indexed arrays with mixed data inside.

use PHPUnit\Framework\TestCase;

class SomeTest extends TestCase
{

    public function testAssociativeArrayNumbersOnlyWillPass()
    {
        $arr = [
            'x' => 1,
            'y' => 1,
        ];

        $this->assertNotContains('test', $arr);
    }

    public function testAssociativeArrayNumbersOnlyWillFail()
    {
        $arr = [
            'x' => 1,
            'y' => 0,
        ];

        $this->assertNotContains('test', $arr);
    }

    public function testIndexedArrayNumbersOnlyWillPass()
    {
        $arr = [
            1,
            1,
        ];

        $this->assertNotContains('test', $arr);
    }

    public function testIndexedArrayNumbersOnlyWillFail()
    {
        $arr = [
            1,
            0,
        ];

        $this->assertNotContains('test', $arr);
    }

    public function testIndexedArrayWithStringsWillPass()
    {
        $arr = [
            'php',
            'phpunit',
            1
        ];

        $this->assertNotContains('test', $arr);
    }

    public function testIndexedArrayWithStringsWillFail()
    {
        $arr = [
            'php',
            'phpunit',
            0,
        ];

        $this->assertNotContains('test', $arr);
    }
}

The result is:

PHPUnit 8.4.3 by Sebastian Bergmann and contributors.

.F.F.F                                                              6 / 6 (100%)

Time: 232 ms, Memory: 4.00 MB

There were 3 failures:

1) SomeTest::testAssociativeArrayNumbersOnlyWillFail
Failed asserting that an array does not contain 'test'.

E:\webserver\home\_development\www\php\sometest\tests\SomeTest.php:28

2) SomeTest::testIndexedArrayNumbersOnlyWillFail
Failed asserting that an array does not contain 'test'.

E:\webserver\home\_development\www\php\sometest\tests\SomeTest.php:48

3) SomeTest::testIndexedArrayWithStringsWillFail
Failed asserting that an array does not contain 'test'.

E:\webserver\home\_development\www\php\sometest\tests\SomeTest.php:70

FAILURES!
Tests: 6, Assertions: 6, Failures: 3.

@sebastianbergmann
Copy link
Owner

Verified. Thank you for the report.

@sebastianbergmann
Copy link
Owner

This is basically due to 0 == 'test'. This operation is performed here.

The issue can be worked around by passing true for the optional parameter $checkForNonObjectIdentityto assertContains() or assertNotContains().

sebastianbergmann added a commit that referenced this issue Nov 13, 2019
@sebastianbergmann sebastianbergmann removed the type/bug Something is broken label Nov 17, 2019
@sebastianbergmann
Copy link
Owner

sebastianbergmann commented Nov 17, 2019

Unfortunately this is expected behaviour in PHPUnit 8. Starting with PHPUnit 9, due in February 2020, assertContains() will perform type-safe comparisons which will solve this problem (see #3426). In the meantime, use the optional parameters for assertContains() to force perform type-safe comparison.

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