单元测试嘲笑 - 对我来说没有意义

时间:2013-03-29 14:31:14

标签: php unit-testing junit mocking phpunit

我正在尝试学习单元测试并且遇到以下情况我无法理解:

  1. 我有一个模型:SalesOrder - 它为电子商务商店中的订单建模
  2. SalesOrder有一个名为gift_message_id
  3. 的属性
  4. 礼品消息ID是一个整数值,是GiftMessage模型的外键
  5. GiftMessage模型有一个方法可以接受订单模型并根据SalesOrder正确加载GiftMessage实例。
  6. 我正在尝试编写一个准确测试此行为的测试,但最终我得到了2个模拟:1为SalesOrder,1为GiftMessage,它没有意义。我在这做错了什么?

    我尝试测试的方法如下:

    public function loadGiftMessageByOrderModel(SalesOrder $order)
    {
        $giftMessageId = $order->getGiftMessageId();
    
        //if the order has a gift message id then load the gift message model and return it
        if ($giftMessageId !== false) {
            return new GiftMessage($giftMessageId);
        }
        return false;
    }
    

    如何对单元进行单元测试,请记住订单和礼品消息数据存储在数据库中。

2 个答案:

答案 0 :(得分:0)

每当你有一个调用构造函数的方法并且在构造函数中完成非平凡的工作时,你就遇到了麻烦。我将从上面看到的最佳选择是让上面的类包含GiftMessageFactory实例。然后,您可以模拟工厂以验证是否使用适当的值和适当的时间调用它。

答案 1 :(得分:0)

当你编写loadGiftMessageByOrderModel函数并解释了GiftMessage构造函数时,我认为你不能轻易地对这段代码进行单元测试。为了对其进行干净的测试,您需要使用构造函数的方法从DB加载GiftMessage。您的构造函数不应该调用与数据库交互的方法。另一个类或方法应该执行该加载,然后调用构造函数。粗略地,这样的事情:

public function loadGiftMessageByOrderModel(SalesOrder $order)
{
    $giftMessageId = $order->getGiftMessageId();

    //if the order has a gift message id then load the gift message model and return it
    if ($giftMessageId !== false) {
        // $giftMessageLoader handles loading from the DB; it doesn't create a GiftMessage object
        $giftMessageRecord = $giftMessageLoader.loadById( $giftMessageId );
        // $giftMessageFactory actually calls the constructor to create a GiftMessage
        return $giftMessageFactory.createFromRecord( $giftMessageRecord );
    }
    return false;
}

然后,您可以模拟$giftMessageLoader.loadById调用,以便控制从数据库返回的内容。您还可以测试$giftMessageFactory是否正确调用GiftMessage构造函数并创建正确的对象。

这里的总体教训是构造函数应该简单。他们可以验证参数,以便正确构造对象,但它们可能不应该调用应用程序的其他重要部分。