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: