ApiCommandTest::commandProvider()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 33
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 33
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 23
nc 1
nop 0
1
<?php
2
3
namespace Stp\SndApi\News\Test\Command;
4
5
use Stp\SndApi\News\Client;
6
use Stp\SndApi\News\Command\ArticleCommand;
7
use Stp\SndApi\News\Command\ArticlesBySectionIdCommand;
8
use Stp\SndApi\News\Command\ImageVersionsCommand;
9
use Stp\SndApi\News\Command\SearchByInstanceCommand;
10
use Stp\SndApi\News\Command\SearchCollectionCommand;
11
use Stp\SndApi\News\Command\SectionByIdCommand;
12
use Stp\SndApi\News\Command\SectionByUniqueNameCommand;
13
use Stp\SndApi\News\Command\SectionsListCommand;
14
use Stp\SndApi\News\Command\ServiceDocumentCommand;
15
use Stp\SndApi\News\Command\SubsectionsListCommand;
16
use Symfony\Component\Console\Application;
17
use Symfony\Component\Console\Tester\CommandTester;
18
19
class ApiCommandTest extends \PHPUnit_Framework_TestCase
20
{
21
    private function initCommand($command, $commandClass, $expectedMethod)
22
    {
23
        $application = new Application();
24
        $application->add(new $commandClass);
25
26
        /** @var Client|\PHPUnit_Framework_MockObject_MockObject $client */
27
        $client = $this->getMockBuilder(Client::class)
28
            ->setConstructorArgs(['key', 'secret', 'sa'])
29
            ->getMock();
30
31
        /** @var ArticleCommand $command */
32
        $command = $application->find($command);
0 ignored issues
show
Documentation introduced by
$command is of type object<Stp\SndApi\News\Command\ArticleCommand>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
33
        $command->setNewsClient($client);
34
35
        $client->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Stp\SndApi\News\Client.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
36
            ->method($expectedMethod)
37
            ->willReturn(['tested']);
38
39
        return $command;
40
    }
41
42
    public function commandProvider()
43
    {
44
        return [
45
            ['news:article:id', ArticleCommand::class, 'getArticle', ['id' => 100]],
46
            ['news:section:articles', ArticlesBySectionIdCommand::class, 'getArticlesBySectionId', [
47
                'id' => 100,
48
                'method' => 'auto',
49
                'parameters' => ['limit=50']
50
            ]],
51
            ['news:search:instance', SearchByInstanceCommand::class, 'searchByInstance', [
52
                'id' => 100,
53
                'contentType' => 'article'
54
            ]],
55
            ['news:search:collection', SearchCollectionCommand::class, 'searchByCollection', [
56
                'ids' => [
57
                    100,
58
                    200
59
                ]
60
            ]],
61
            ['news:section:id', SectionByIdCommand::class, 'getSectionById', [
62
                'id' => 100
63
            ]],
64
            ['news:section:uniquename', SectionByUniqueNameCommand::class, 'getSectionByUniqueName', [
65
                'name' => 'test'
66
            ]],
67
            ['news:sections:list', SectionsListCommand::class, 'getSectionsList', []],
68
            ['news:image:versions', ImageVersionsCommand::class, 'getImageVersions', []],
69
            ['news:servicedocument', ServiceDocumentCommand::class, 'getServiceDocument', []],
70
            ['news:subsections:list', SubsectionsListCommand::class, 'getSubsectionsList', [
71
                'sectionId' => 100
72
            ]]
73
        ];
74
    }
75
76
    /**
77
     * @dataProvider commandProvider
78
     */
79
    public function testExecute($commandName, $commandClass, $commandMethod, $commandParams)
80
    {
81
        $command = $this->initCommand($commandName, $commandClass, $commandMethod);
82
83
        $commandTester = new CommandTester($command);
84
        $commandTester->execute(
85
            $commandParams + [
86
                '--secret' => 'secret',
87
                '--publicationId' => 'sa'
88
            ]
89
        );
90
91
        $this->assertContains('tested', $commandTester->getDisplay());
92
    }
93
}
94