Php 无法模拟模型::where()并阻止测试查询数据库

Php 无法模拟模型::where()并阻止测试查询数据库,php,laravel,phpunit,mockery,Php,Laravel,Phpunit,Mockery,在我的控制器中,我使用的是MyModel::where(…),它在我的一个测试期间调用数据库。我以为我可以用下面的内容来重载它,但它仍然在查询数据库。我可以做些什么来确保我的测试仍然需要调用::其中,但返回模拟模型,以便我可以继续测试此控制器方法的其余部分 MyModel::shouldReceive('where') ->once() ->with('param1', 'param2') ->andReturn($mockedModel); 使用并创建一个只返回

在我的控制器中,我使用的是
MyModel::where(…)
,它在我的一个测试期间调用数据库。我以为我可以用下面的内容来重载它,但它仍然在查询数据库。我可以做些什么来确保我的测试仍然需要调用
::其中
,但返回模拟模型,以便我可以继续测试此控制器方法的其余部分

MyModel::shouldReceive('where')
  ->once()
  ->with('param1', 'param2')
  ->andReturn($mockedModel);
使用并创建一个只返回所需数据的新函数

如果你没有读过《拉威尔:从学徒到工匠》,我会建议你读。将帮助您了解所有这些内容的结构。

使用并创建一个新函数,该函数只返回您想要的数据


如果你没有读过《拉威尔:从学徒到工匠》,我会建议你读。将帮助您了解所有这些是如何构造的。

首先,您必须了解为什么不能模拟
where
方法。这是因为类
illumb\Database\Eloquent\Model
(Eloquent是它的别名)没有显式声明
where
方法。这个方法是通过神奇的方法
\uuu callStatic
\uu call
调用的,实际上,它是
照亮\数据库\雄辩\构建器
()的一个方法

然后,您有几个选项:

  • 您可以接受在测试中调用数据库,并在断言之前定义一个真实的上下文。您的测试将不那么单一,但我们可以在大多数情况下处理

  • @michaelcurry溶液是一种很好的溶液。您可以使用查询范围或其他体系结构构建自己的抽象层(例如,在模型中自己注入查询生成器),以生成更可测试的代码

  • [从未尝试过]您可以直接模拟
    DB
    facade以完全绕过数据库。您需要对Laravel核心有很好的理解,但这可能是编写“纯”单元测试的好方法


  • 无论如何,请不要犹豫,深入了解Laravel源代码。代码很清楚,真正重要的类很少。这对于真正发挥框架的威力至关重要。

    首先,您必须理解为什么不能模仿
    where
    方法。这是因为类
    illumb\Database\Eloquent\Model
    (Eloquent是它的别名)没有显式声明
    where
    方法。这个方法是通过神奇的方法
    \uuu callStatic
    \uu call
    调用的,实际上,它是
    照亮\数据库\雄辩\构建器
    ()的一个方法

    然后,您有几个选项:

  • 您可以接受在测试中调用数据库,并在断言之前定义一个真实的上下文。您的测试将不那么单一,但我们可以在大多数情况下处理

  • @michaelcurry溶液是一种很好的溶液。您可以使用查询范围或其他体系结构构建自己的抽象层(例如,在模型中自己注入查询生成器),以生成更可测试的代码

  • [从未尝试过]您可以直接模拟
    DB
    facade以完全绕过数据库。您需要对Laravel核心有很好的理解,但这可能是编写“纯”单元测试的好方法


  • 无论如何,请不要犹豫,深入了解Laravel源代码。代码很清楚,真正重要的类很少。这对于真正发挥框架的威力至关重要。

    对于这种情况,这是一个很好的建议。。。但它似乎仍在访问数据库。这是一个很好的建议。。。但它似乎仍在冲击数据库。