PhpSpec - 检查方法 returns 一个整数而不是 "willReturn(x)"

PhpSpec - check method returns an integer rather than "willReturn(x)"

有没有一种方法可以测试 getNumberOfProductsForCategory 方法将 return 一个整数而不是 特定的 值(在本例中为 18) ?

我觉得只是测试“18”,虽然现在是正确的,但会使我的测试变得非常脆弱,因为该值可能会在将来的某个时候发生变化,这意味着测试将失败。

这是我的 PhpSpec 函数(为简洁起见进行了缩减):

    function it_returns_something_if_products_exist(
       ProductRepository $productRepository, 
       Category $category
    )
    {
       $category->getId()->willReturn(268);
       $productRepository->getNumberOfProductsForCategory($category)->willReturn(18);

       // call method here
    }

这是我的存储库方法:

/**
 * @param Category $category
 *
 * @return mixed
 */
public function getNumberOfProductsForCategory(Category $category)
{
    $dql = 'SELECT COUNT(tvp)
                FROM \CRMPicco\ProductBundle\Entity\Product tvp
            WHERE tvp.category = :category';

    return $this->getEntityManager()
        ->createQuery($dql)
        ->setParameter('category', $category)
        ->getSingleScalarResult();
}

您没有在发布的代码中测试任何内容。 $productRepository$categorystubs 并且您所做的调用配置了它们的行为。

例如,

$category->getId()->willReturn(268);

在调用其方法 getId() 时将对象 $category(模仿 Category 类型对象的行为)配置为 return 268 .

没有这个配置,$category->getId() returns NULL.

其实phpspec is not a testing tool, it is a specification tool. It is not used to test the behaviour of the code but to describe its behaviour. Take a look of what the creator of phpspec says about the limitations of phpspec。特别检查限制 #8:

The thing is, PhpSpec was not designed for integration tests – in fact, it wasn’t designed for testing anything really. It was designed as a tool to help you come up with well-designed classes.

it 从函数名 it_returns_blah_blah_blah() 指的是你描述的 class 而 class 是提供名称的 class规范。例如,如果您发布的函数是 class FormatterSpec 的成员,则表示它描述了 class Formatter.

的行为

方法的名称 it_returns_something_if_products_exist() 应该表明它所描述的功能。

假设您要描述方法 Formatter::formatNumberOfProducts()。它有两个参数(Category $categoryProductRepository $productRepository),return 是一个字符串,可以是 1 productX products(将 X 替换为产品中的实际数量类别)。

规范可能如下所示:

class FormatterSpec
{
    function it_formats_number_of_products_when_they_are_many(
       ProductRepository $productRepository, 
       Category $category
    )
    {
        // prepare the stubs
        $category->getId()->willReturn(268);
        $productRepository->getNumberOfProductsForCategory($category)
            ->willReturn(18);

        // describe the behaviour
        $this->formatNumberOfProducts($category, $productRepository)
            ->shouldReturnString();
        $this->formatNumberOfProducts($category, $productRepository)
            ->shouldBe('18 products');
    }


    function it_formats_number_of_products_when_there_is_only_one(
       ProductRepository $productRepository, 
       Category $category
    )
    {
        // prepare the stubs
        $category->getId()->willReturn(268);
        $productRepository->getNumberOfProductsForCategory($category)
            ->willReturn(1);

        // describe the behaviour
        $this->formatNumberOfProducts($category, $productRepository)
            ->shouldReturnString();
        $this->formatNumberOfProducts($category, $productRepository)
            ->shouldBe('1 product');
    }
}

您需要配置存根,因为您知道方法 formatNumberOfProducts() 调用了它们的一些方法。您使用存根是因为您不关心 $productRepository 如何获取其数据;您只关心它 return 是一个数字,并且所描述的方法必须以特定方式使用该数字。