好的,可能是个坏榜样。这是一个实际的例子。我想要从购物车类中对total()方法进行单元测试,以查看该值是否是我认为应该是的值,它使用getAll()(购物车项目),subTotal()和shipping()方法。你可以使用PHPUnit测试total()吗?
class Cart extends ObjectModel
{
protected $uniqueID = 10;
public function getAll()
{
return $this->execute("SELECT *, cart.id AS cart_id FROM cart LEFT JOIN products ON products.id = cart.product_id WHERE cart.unique_id = ? AND cart.quantity > '0' AND cart.deleted_at IS NULL ", [$this->uniqueID] );
}
public function subTotal()
{
$subTotal = 0;
foreach($this->getAll() as $row){
$subTotal += ( $row->quantity * $row->cart_price );
}
return $subTotal;
}
public function total()
{
return $this->subTotal() + $this->shipping();
}
public function shipping()
{
if(isset($_SESSION[SALT.'shipping']) && $_SESSION[SALT.'shipping'] != ''){
return $_SESSION[SALT.'shipping'];
}
/* OR RETURN DEFAULT IF SHIPPING IS NOT SET */
return 0;
}
}
execute方法如下,ObjectModel类没有构造函数方法
public function execute($query, array $array) {
$query = Db::conn()->prepare($query);
$query->execute($array);
return $query->fetchAll(PDO::FETCH_OBJ);
}
Db :: conn()只是PDO数据库句柄。
答案 0 :(得分:0)
该类不适合单元测试,因为它与数据库紧密耦合。在单元测试中,您希望在外部组件的隔离中测试被测试对象(此处为:数据库)。通常,您使用 test double 模拟或存储外部组件。
由于数据库实例在ObjectModel
的执行方法中是硬编码的,因此您无法使用测试双精度替换它。您可以将测试转换为集成测试,并将数据库连接更改为测试数据库,然后在测试设置方法中填充预期值。
如果您根本不想使用数据库,则可以自我分流被测试对象。这意味着,您使用测试对象本身的测试双,并使execute返回测试用例的预期值。