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

Erroneous TooFewArguments on combination of data provider and dependent test #113

Open
remorhaz opened this issue Jul 10, 2021 · 6 comments
Labels
enhancement New feature or request

Comments

@remorhaz
Copy link

remorhaz commented Jul 10, 2021

In my case, test case class has the following structure:

<?php

class MyTest extends \PHPUnit\Framework\TestCase
{

    public function testOne(): string
    {
        // ...
        return 'bar';
    }

    /**
     * @dataProvider providerFoo
     * @depends testOne
     */
    public function testSecond(string $foo, string $bar): void
    {
        // ...
    }

    /**
     * @return iterable<string, array{string}>
    public function providerFoo(): iterable
    {
        return [['foo']];
    }
}

In this case, testSecond() method gets $foo = 'foo' and $bar = 'bar' arguments; but Psalm reports TooFewArguments (probably ignoring dependency if data provider is set).

P.S.: Anyone please tell me how to suppress this bug until it gets fixed. Adding @psalm-suppress TooFewArguments both in provider or test method docblocks doesn't help.

@weirdan
Copy link
Member

weirdan commented Jul 10, 2021

Currently the plugin has no idea what @depends mean.

Anyone please tell me how to suppress this bug until it gets fixed. Adding @psalm-suppress TooFewArguments both in provider or test method docblocks doesn't help.

You may try to suppress it via config file. Didn't test it myself, but I think it might work:

        <TooFewArguments>
            <errorLevel type="suppress">
                <referencedFunction name="Tests\TestCase::testThatFails" />
            </errorLevel>
        </TooFewArguments>

@weirdan
Copy link
Member

weirdan commented Jul 10, 2021

Dev notes:

When a test receives input from both a @dataProvider method and from one or more tests it @depends on, the arguments from the data provider will come before the ones from depended-upon tests

The following is not really clear:

The result of a test that uses data providers cannot be injected into a depending test.

@weirdan weirdan added the enhancement New feature or request label Jul 10, 2021
@weirdan
Copy link
Member

weirdan commented Jul 10, 2021

You may try to suppress it via config file. Didn't test it myself, but I think it might work

Yep, the following does work:

Feature: Suppression
  In order to avoid false positives
  As a Psalm user
  I need to be able to suppress issues emitted by the plugin

  Scenario: Can suppress TooFewArguments via config
    Given I have the following config
      """
      <?xml version="1.0"?>
      <psalm totallyTyped="true" %s>
        <projectFiles>
          <directory name="."/>
          <ignoreFiles> <directory name="../../vendor"/> </ignoreFiles>
        </projectFiles>
        <plugins>
          <pluginClass class="Psalm\PhpUnitPlugin\Plugin"/>
        </plugins>
        <issueHandlers>
          <TooFewArguments>
            <errorLevel type="suppress">
              <referencedFunction name="NS\MyTestCase::testConsumer" />
            </errorLevel>
          </TooFewArguments>
        </issueHandlers>
      </psalm>
      """
    And I have the following code
      """
      <?php
      namespace NS;
      use PHPUnit\Framework\TestCase;

      class MyTestCase extends TestCase
      {
        public function testProducer(): int
        {
          return 42;
        }

        /**
         * @depends testProducer
         * @dataProvider provide
         */
        public function testConsumer(int $provided, int $dependedUpon): void {}

        /** @return iterable<int,array{int}> */
        public function provide() {
          yield [1];
        }
      }
      """
    When I run Psalm
    Then I see no errors

@remorhaz
Copy link
Author

The result of a test that uses data providers cannot be injected into a depending test.

This means that if you make testSecond() dependent of testOne() (like in my example), then testOne() cannot use data provider (but testSecond() can, as it does in my example).

@weirdan
Copy link
Member

weirdan commented Jul 10, 2021

I'm curious what would happen if it does?

@remorhaz
Copy link
Author

I'm curious what would happen if it does?

Just as written - it doesn't inject any data from data-provided test, I'm just getting null in "dependent" argument (or TypeError if it's type-hinted).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants