php - PHP 单元测试——这是否被过度嘲笑了?-- 公共方法循环/调用其他公共方法
问题描述
功能性
我有一个 Laravel 项目,我在其中扩展Illuminate\Database\Eloquent\Builder
为一个AbstractSearch
类,以引入一个params()
方法,该方法在扩展时调用applyParams()
要定义的抽象方法AbstractSearch
。
例子:
$models = (new ModelSearch)
->params(['name' => 'Model', 'createdBefore' => now()])
->with(['modelCategory', 'modelType'])
->paginate();
applyParams()
负责从底层查询中获取数组参数params()
并正确构建底层Illuminate\Database\Query\Builder
查询。
该类AbstractSearch
允许通过受保护的$casts
属性和castParams(array $params = [])
方法转换这些参数。
castParams()
遍历受保护的$casts
属性并调用$this->castParam($params, $field, $cast)
每个元素。
现在,两者castParams()
和castParam()
都是公共方法,即使以castParam()
这种方式调用的可能性几乎为零。
相关节选AbstractSearch
:
public function params(array $params = [])
{
return $this->applyParams(
$this->prepareParams($params)
);
}
abstract function applyParams(array $params = []);
public function prepareParams(array $params = []) : array
{
return $this->castParams(
$this->applyDefaults($params)
);
}
public function applyDefaults(array $params = []) : array
{
foreach ($this->defaults as $field => $value) {
data_fill($params, $field, $value);
}
return $params;
}
public function getCasts()
{
return $this->casts;
}
public function castParams(array $params = []) : array
{
foreach ($this->getCasts() as $field => $cast) {
$this->castParam($params, $field, $cast);
}
return $params;
}
public function castParam(&$params, $field, $cast)
{
if (! isset($params[$field])) {
return;
}
switch ($cast) {
case 'date':
case 'datetime':
if (! $params[$field] instanceof Carbon) {
$params[$field] = Carbon::parse($params[$field]);
}
break;
default:
break;
}
}
测试
我对这两种方法都有单元测试。大部分测试都是castParam()
为了确保正确完成铸造。
的单元测试是通过对期望各种调用castParams()
的类的部分模拟来完成的。AbstractSearch
castParam()
问题
我最近重新阅读了一些单元测试原则,这些原则让我质疑这门课的设置。您可以从上面的摘录中看到,有很多公共方法可能应该受到保护。事实上,唯一需要公开的方法是params()
.
从逻辑上讲,这params()
应该是唯一的公共方法;但是,params()
依赖于抽象方法applyParams()
,因此任何测试params()
都必须在扩展类上完成,因为结果取决于所做的事情applyParams()
。
所以...
我用上面两段话把自己说对了吗?这听起来对我来说是正确的,但它将涉及
params()
返回一个实例的测试,以及对 Builder 的底层及其查询Illuminate\Database\Eloquent\Builder
进行预期更改的测试。Illuminate\Database\Query\Builder
我不完全确定这是否可能。回到
castParams()
部分模拟的期望,它会调用castParam()
几次。如果两者都castParams()
保留castParam()
公共方法,并且测试应该关注可观察的行为,那么如果我同时测试两者,我不会有多余的测试吗?还是因为将经过彻底测试,所以castParam()
在我的测试中模拟调用通常是可以接受的?(编辑:这个问题通常也适用于调用其他公共方法的任何公共方法。)castParams()
castParam()
解决方案
推荐阅读
- angular - Angular如何修补表单数组中的值
- java - C# 中的 BigInteger.intValue() 等价物
- python - 如何使用python发送电子邮件
- swift - 是什么导致此代码中出现“EXC_Bad_Instruction”错误?
- angular - 理解 Angular RouterLink 选择器规范中的 ":not" 语法
- angular - TypeError:无法从 kendo 库组件中设置未定义的属性“forceExpand”
- sql - 在sql中搜索RFID的最快方法
- python - ModuleNotFoundError:没有在同一个文件夹项目中命名的模块
- xamarin - 从 Gstreaming 到 VLC 的 udp 流式传输不起作用
- python - pyautogui 在知道 2 个角的特定区域创建屏幕截图