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 |
||
7 | class ModelTest extends PHPUnit_Framework_TestCase |
||
8 | { |
||
9 | /** |
||
10 | * Instance of DatabaseConnection used in test. |
||
11 | */ |
||
12 | protected $databaseConnection; |
||
13 | |||
14 | /** |
||
15 | * Instance of Model used in test. |
||
16 | */ |
||
17 | protected $model; |
||
18 | |||
19 | /** |
||
20 | * Instance of SqlStatement used in test. |
||
21 | */ |
||
22 | protected $sqlStatement; |
||
23 | |||
24 | public function setUp() |
||
25 | { |
||
26 | $databaseConnectionStringFactory = |
||
27 | m::mock('Pyjac\ORM\DatabaseConnectionStringFactoryInterface'); |
||
28 | |||
29 | $databaseConnectionStringFactory->shouldReceive('createDatabaseSourceString') |
||
30 | ->with(['DRIVER' => 'sqlite', 'HOSTNAME' => '127.0.0.1', 'USERNAME' => '', 'PASSWORD' => '', 'DBNAME' => 'potatoORM', 'PORT' => '54320'])->once()->andReturn('sqlite::memory:'); |
||
31 | |||
32 | $this->databaseConnection = m::mock('Pyjac\ORM\DatabaseConnection'); |
||
33 | |||
34 | $this->sqlStatement = m::mock('\PDOStatement'); |
||
35 | |||
36 | $this->model = $this->getMockForAbstractClass('Pyjac\ORM\Model', [$this->databaseConnection]); |
||
37 | } |
||
38 | |||
39 | public function testGetTableNameReturnsCorrectTableName() |
||
48 | |||
49 | public function testGetReturnsAnObjectWhenIdIsFoundInDatabase() |
||
59 | |||
60 | View Code Duplication | public function testGetReturnNullWhenIdNotFoundInDatabase() |
|
|
|||
61 | { |
||
62 | $this->databaseConnection->shouldReceive('prepare')->once()->andReturn($this->sqlStatement); |
||
63 | $this->sqlStatement->shouldReceive('setFetchMode'); |
||
64 | $this->sqlStatement->shouldReceive('execute'); |
||
65 | $this->sqlStatement->shouldReceive('rowCount')->once()->andReturn(0); |
||
66 | |||
67 | $this->assertEquals(null, $this->model->get(1)); |
||
68 | } |
||
69 | |||
70 | public function testAllReturnsAnArrayOfObjectsWhenValuesAreInDatabase() |
||
71 | { |
||
72 | $this->databaseConnection->shouldReceive('prepare')->once()->andReturn($this->sqlStatement); |
||
73 | $this->sqlStatement->shouldReceive('execute'); |
||
74 | $this->sqlStatement->shouldReceive('fetchAll')->once()->andReturn([new stdClass(), new stdClass()]); |
||
75 | $this->assertContainsOnlyInstancesOf('stdClass', $this->model->all()); |
||
76 | } |
||
77 | |||
78 | public function testUpdateChangesTheValueOfObjectInDatabase() |
||
79 | { |
||
80 | $this->model->setProperties(['id' => 2, 'name' => 'pyjac', 'age' => '419']); |
||
81 | $this->databaseConnection->shouldReceive('prepare')->once()->andReturn($this->sqlStatement); |
||
82 | $this->sqlStatement->shouldReceive('execute'); |
||
83 | $this->sqlStatement->shouldReceive('rowCount')->once()->andReturn(1); |
||
84 | |||
85 | $this->assertEquals(1, $this->model->update()); |
||
86 | } |
||
87 | |||
88 | View Code Duplication | public function testCreateObjectInDatabase() |
|
89 | { |
||
90 | $this->model->setProperties(['name' => 'pyjac', 'age' => '419']); |
||
91 | $this->databaseConnection->shouldReceive('prepare')->once()->andReturn($this->sqlStatement); |
||
92 | $this->sqlStatement->shouldReceive('execute'); |
||
93 | $this->sqlStatement->shouldReceive('rowCount')->once()->andReturn(1); |
||
94 | |||
95 | $this->assertEquals(1, $this->model->create()); |
||
96 | } |
||
97 | |||
98 | public function testSaveShouldCreateNewModelInDatabaseWhenIdNotPresent() |
||
99 | { |
||
100 | $this->model->setProperties(['name' => 'pyjac', 'age' => '419']); |
||
101 | $this->databaseConnection->shouldReceive('prepare')->once()->andReturn($this->sqlStatement); |
||
102 | $this->sqlStatement->shouldReceive('execute'); |
||
103 | $this->sqlStatement->shouldReceive('rowCount')->once()->andReturn(1); |
||
104 | $this->assertEquals(1, $this->model->save()); |
||
105 | } |
||
106 | |||
107 | public function testSaveShouldUpdateModelInDatabaseIfIdIsPresent() |
||
108 | { |
||
109 | $this->model->setProperties(['id' => 2, 'name' => 'pyjac', 'age' => '419']); |
||
110 | $this->databaseConnection->shouldReceive('prepare')->once()->andReturn($this->sqlStatement); |
||
111 | $this->sqlStatement->shouldReceive('execute'); |
||
112 | $this->sqlStatement->shouldReceive('rowCount')->once()->andReturn(1); |
||
113 | $this->assertEquals(1, $this->model->save()); |
||
114 | } |
||
115 | |||
116 | public function testGetPropertiesReturnsExpectedArrayValues() |
||
117 | { |
||
118 | $values = ['id' => 2, 'name' => 'pyjac', 'age' => '419']; |
||
119 | $this->model->setProperties($values); |
||
120 | |||
121 | $this->assertEquals($values, $this->model->getProperties()); |
||
122 | } |
||
123 | |||
124 | View Code Duplication | public function testDeleteReturnsTrueWhenModelIsSuccessfullyRemovedFromDatabase() |
|
125 | { |
||
126 | $this->databaseConnection->shouldReceive('prepare')->once()->andReturn($this->sqlStatement); |
||
127 | $this->sqlStatement->shouldReceive('execute'); |
||
128 | $this->sqlStatement->shouldReceive('rowCount')->once()->andReturn(1); |
||
129 | |||
130 | $this->assertEquals(true, $this->model->delete(1)); |
||
131 | } |
||
132 | |||
133 | View Code Duplication | public function testDeleteReturnsFalseWhenModelWasNotDeletedFromDatabase() |
|
134 | { |
||
135 | $this->databaseConnection->shouldReceive('prepare')->once()->andReturn($this->sqlStatement); |
||
136 | $this->sqlStatement->shouldReceive('execute'); |
||
137 | $this->sqlStatement->shouldReceive('rowCount')->once()->andReturn(0); |
||
138 | |||
139 | $this->assertEquals(false, $this->model->delete(1)); |
||
140 | } |
||
141 | |||
142 | public function testMagicMethodsReturnCorrectResult() |
||
143 | { |
||
144 | $this->model->id = '10'; |
||
145 | $this->model->name = 'Pyjac'; |
||
146 | $this->model->age = '60'; |
||
147 | |||
148 | $this->assertEquals($this->model->name, 'Pyjac'); |
||
149 | $this->assertEquals($this->model->id, '10'); |
||
150 | $this->assertEquals($this->model->age, '60'); |
||
151 | $this->assertEquals($this->model->jac, null); |
||
152 | } |
||
153 | |||
154 | public function testCreateModelWithNoParameter() |
||
159 | } |
||
160 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.