Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
27 | class CreateOrganizationCommandTest extends TestCase |
||
28 | { |
||
29 | private $commandTester; |
||
30 | |||
31 | private $command; |
||
32 | |||
33 | /** |
||
34 | * @var QuestionHelper |
||
35 | */ |
||
36 | private $question; |
||
37 | |||
38 | public function setUp() |
||
39 | { |
||
40 | $application = new Application(); |
||
41 | $application->add(new CreateOrganizationCommand()); |
||
42 | $this->command = $application->get('swp:organization:create'); |
||
43 | $this->question = $this->command->getHelper('question'); |
||
44 | } |
||
45 | |||
46 | /** |
||
47 | * @covers \SWP\Bundle\MultiTenancyBundle\Command\CreateOrganizationCommand |
||
48 | */ |
||
49 | public function testExecuteWhenCreatingNewOrganization() |
||
63 | |||
64 | /** |
||
65 | * @covers \SWP\Bundle\MultiTenancyBundle\Command\CreateOrganizationCommand |
||
66 | */ |
||
67 | View Code Duplication | public function testExecuteWhenCreatingDefaultOrganization() |
|
84 | |||
85 | /** |
||
86 | * @expectedException \InvalidArgumentException |
||
87 | * @covers \SWP\Bundle\MultiTenancyBundle\Command\CreateOrganizationCommand |
||
88 | */ |
||
89 | View Code Duplication | public function testExecuteWhenDefaultTenantExists() |
|
90 | { |
||
91 | $organization = new Organization(); |
||
92 | $organization->setCode('123456'); |
||
93 | $this->command->setContainer($this->getMockContainer($organization)); |
||
94 | $this->commandTester = new CommandTester($this->command); |
||
95 | |||
96 | $this->commandTester->execute([ |
||
97 | 'command' => $this->command->getName(), |
||
98 | '--default' => true, |
||
99 | ]); |
||
100 | } |
||
101 | |||
102 | /** |
||
103 | * @covers \SWP\Bundle\MultiTenancyBundle\Command\CreateOrganizationCommand |
||
104 | */ |
||
105 | public function testExecuteDisabledOrganization() |
||
106 | { |
||
107 | $organization = new Organization(); |
||
108 | $organization->setCode('123456'); |
||
109 | $this->command->setContainer($this->getMockContainer(null, $organization, 'Example')); |
||
110 | $this->commandTester = new CommandTester($this->command); |
||
111 | $this->commandTester->setInputs(['Example']); |
||
112 | $this->commandTester->execute([ |
||
113 | 'command' => $this->command->getName(), |
||
114 | '--disabled' => true, |
||
115 | ]); |
||
116 | |||
117 | $this->assertEquals( |
||
118 | 'Please enter name:Organization Example (code: 123456) has been created and disabled!', |
||
119 | trim($this->commandTester->getDisplay()) |
||
120 | ); |
||
121 | } |
||
122 | |||
123 | private function getMockContainer($mockOrganization = null, $mockedOrganizationInFactory = null, $name = OrganizationInterface::DEFAULT_NAME) |
||
169 | |||
170 | /** |
||
171 | * @param $input |
||
172 | * |
||
173 | * @return resource |
||
174 | */ |
||
175 | View Code Duplication | protected function getInputStream($input) |
|
183 | } |
||
184 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the parent class: