在我的模特中:
class UsersModel
{
public function getUsers()
{
return SELECT id,username,rights FROM database
}
}
结果是:
array{
array{'id' => 1, 'username' => 'a', 'rights' => 4},
array{'id' => 2, 'username' => 'b', 'rights' => 8},
array{'id' => 4, 'username' => 'c', 'rights' => 7},
}
然后格式化:
class Helper
{
function formatUsers (array $source)
{
foreach ($source as $item)
{
$item['usernameF'] = $item['username'].'.'.$item['id'];
}
return $source;
}
}
结果是:
array{
array{'id' => 1, 'username' => 'a', 'rights' => 4, 'usernameF' => 'a.1'},
array{'id' => 2, 'username' => 'b', 'rights' => 8, 'usernameF' => 'b.2'},
array{'id' => 4, 'username' => 'c', 'rights' => 7, 'usernameF' => 'c.4'}
}
并在视图中输出:
foreach ($users as $item)
{
echo $item['usernameF'].' = '.$item['rights'].'<br>';
}
到目前为止一直很好,现在让我们测试一下。
testModel:
assertEquals ($result, array{
array{'id' => 1, 'username' => 'a', 'rights' => 4, 'usernameF' => 'a.1'},
array{'id' => 2, 'username' => 'b', 'rights' => 8, 'usernameF' => 'b.2'},
array{'id' => 4, 'username' => 'c', 'rights' => 7, 'usernameF' => 'c.4'}
});
testHelper:
这里遇到了困难。我可以模拟getUsers()
方法来强制执行结果。
$mock->setMock ($this->once()->method('getUsers')->willReturn(array{
array{'id' => 1, 'username' => 'a', 'rights' => 4},
array{'id' => 2, 'username' => 'b', 'rights' => 8},
array{'id' => 4, 'username' => 'c', 'rights' => 7}
});
assertEquals ($result, array{
array{'id' => 1, 'username' => 'a', 'rights' => 4, 'usernameF' => 'a.1'},
array{'id' => 2, 'username' => 'b', 'rights' => 8, 'usernameF' => 'b.2'},
array{'id' => 4, 'username' => 'c', 'rights' => 7, 'usernameF' => 'c.4'}
}
但是如果DB方案改变怎么办?如果我不小心输错了字段,请说“usernmame
”。结果将是:
array{
array{'id' => 1, 'usernmame' => 'a', 'rights' => 4},
array{'id' => 2, 'usernmame' => 'b', 'rights' => 8},
array{'id' => 4, 'usernmame' => 'c', 'rights' => 7},
}
当然模型测试失败了,所以我也改了:
testModel:
assertEquals ($result, array{
array{'id' => 1, 'usernmame' => 'a', 'rights' => 4, 'usernameF' => 'a.1'},
array{'id' => 2, 'usernmame' => 'b', 'rights' => 8, 'usernameF' => 'b.2'},
array{'id' => 4, 'usernmame' => 'c', 'rights' => 7, 'usernameF' => 'c.4'}
});
所以所有测试都通过 - 但在生产中,视图将以“错误的索引;用户名”失败!那么最好的方法是什么?
答案 0 :(得分:1)
不要验证超过需要。 formatUsers
方法接受数组,除了username
和id
之外,它不关心它来自何处,也不关心它具有什么键。在测试此方法时,“模拟”数据是完全正确的。
如果架构发生了变化怎么办?这不是关于您的测试的问题,而是关于您的代码的问题,这是完全有效的问题。良好设计的目标是尽量减少每个变化的范围。在您的情况下,有多个对象知道字段的名称。如果您正在传递具有username
属性的对象而不是数组,那么您可以在代码中只有一个位置将DB结果映射到对象,并将DB中使用的名称与名称分离在代码中使用。
顺便说一句,您可以使用array_map
代替foreach循环