phpunit9模拟方法仍在执行
我正在尝试嘲笑打电话给Twilio Rest API进行我写的测试。这是我编写要模拟的代码:
$message = $twilioTest->getMockedMessageInstance(['body' => 'This won\'t exist']);
$twilioStub = $this->getMockBuilder(Twilio::class)->getMock();
$twilioStub->expects($this->once())->method('retrieveLastTextFromBot')->willReturn($message);
retievelastTextFrombot
方法的内容是:
$messages = $this->twilioClient->messages->read([
'to' => TwilioDefinitions::getToNumber(),
'from' => getenv('TWILIO_NUMBER'),
], 1);
if (count($messages) !== 1) {
throw new NoExtantTextException('No previous message from ' . getenv('TWILIO_NUMBER') . ' to ' . TwilioDefinitions::getToNumber());
}
return $messages[0];
但是,显然,我不希望retievelastTextTextFrombot
methode ,这就是为什么我嘲笑它。不过,由于某些原因,该方法正在执行,我知道,因为在我的phpunit失败中,我会遇到此错误:
1) CronControllerTest::testRemindMethodErrorHandling
Twilio\Exceptions\RestException: [HTTP 403] Unable to fetch page: Resource not accessible with Test Account Credentials
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/vendor/twilio/sdk/src/Twilio/Page.php:58
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/vendor/twilio/sdk/src/Twilio/Page.php:34
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/vendor/twilio/sdk/src/Twilio/Rest/Api/V2010/Account/MessagePage.php:23
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/vendor/twilio/sdk/src/Twilio/Rest/Api/V2010/Account/MessageList.php:147
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/vendor/twilio/sdk/src/Twilio/Rest/Api/V2010/Account/MessageList.php:96
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/vendor/twilio/sdk/src/Twilio/Rest/Api/V2010/Account/MessageList.php:118
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/app/YmcaScheduler/Utility/Twilio.php:33
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/app/YmcaScheduler/Controller/CronController.php:29
/Users/adammcgurk/Desktop/ymca-scheduler-brains/tests/CronControllerTest.php:22
twilio.php中的第33行是RETRIEVELASTTEXTTEXTFROMBOT()
方法的第四行,所以它正在执行。
也许我只是不正确地理解嘲笑,但是我认为会发生的事情是根本不会执行该方法,而是phpunit只会强迫数据返回。
我如何在不实际执行的情况下模拟Phpunit的方法?
I'm trying to mock a call to the Twilio Rest API for a test I'm writing. This is the code I've written to mock:
$message = $twilioTest->getMockedMessageInstance(['body' => 'This won\'t exist']);
$twilioStub = $this->getMockBuilder(Twilio::class)->getMock();
$twilioStub->expects($this->once())->method('retrieveLastTextFromBot')->willReturn($message);
And the contents of the retrieveLastTextFromBot
method are:
$messages = $this->twilioClient->messages->read([
'to' => TwilioDefinitions::getToNumber(),
'from' => getenv('TWILIO_NUMBER'),
], 1);
if (count($messages) !== 1) {
throw new NoExtantTextException('No previous message from ' . getenv('TWILIO_NUMBER') . ' to ' . TwilioDefinitions::getToNumber());
}
return $messages[0];
But obviously, I don't want the contents of the retrieveLastTextFromBot
method to execute, that's why I'm mocking it. For some reasons though, that method is executing, and I know that because in my phpunit failure I'm getting this error:
1) CronControllerTest::testRemindMethodErrorHandling
Twilio\Exceptions\RestException: [HTTP 403] Unable to fetch page: Resource not accessible with Test Account Credentials
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/vendor/twilio/sdk/src/Twilio/Page.php:58
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/vendor/twilio/sdk/src/Twilio/Page.php:34
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/vendor/twilio/sdk/src/Twilio/Rest/Api/V2010/Account/MessagePage.php:23
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/vendor/twilio/sdk/src/Twilio/Rest/Api/V2010/Account/MessageList.php:147
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/vendor/twilio/sdk/src/Twilio/Rest/Api/V2010/Account/MessageList.php:96
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/vendor/twilio/sdk/src/Twilio/Rest/Api/V2010/Account/MessageList.php:118
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/app/YmcaScheduler/Utility/Twilio.php:33
/Users/adammcgurk/Desktop/ymca-scheduler-brains/src/app/YmcaScheduler/Controller/CronController.php:29
/Users/adammcgurk/Desktop/ymca-scheduler-brains/tests/CronControllerTest.php:22
And line 33 in Twilio.php is that fourth line of the retrieveLastTextFromBot()
method, so it's executing.
And maybe I just understand mocking incorrectly, but what I thought was going to happen was the method wouldn't be executed at all, instead, phpunit would just force data to be returned from it.
How can I mock a method in phpunit without it actually being executed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
工作示例
我以一个工作示例开始这个答案。您可以按照此答案中的解释进行两件事。当答案的部分适合您的情况时,请使用额外的信息/详细信息更新您的问题。
将此代码添加到
tests/twiliotest.php
:结果
执行测试:
请验证此代码是否也适用于您。如果没有,请告诉我您使用哪些作曲家库版本。考虑将此信息添加到您的问题
Composer Show -I
。结果应该是:
我希望您以某种方式调用
retievelastTextFrombot
在其他内容上,模拟
对象如果上述代码工作,我怀疑您以某种方式调用方法
retrievelastTextFrombot
在生产代码上,而不是模拟对象,或者您可以从其他位置执行两次方法。要找出真正发生的事情,将以下代码添加到
RETIEVELASTTEXTFROMBOT
(在您的生产代码中):如果它返回
sut> sut
(系统正在测试的系统)的文件,则现在,您确定您没有在模拟对象上执行该方法。您可能会看到一个不同的文件,在这种情况下,检查您的代码以查看您执行的位置。检查您的测试以查看构造函数中传递的实例。如果否则,请让我知道
debug_backtrace()
的结果是什么,并考虑使用结果更新您的问题,以便我们继续提供帮助,因为并非所有代码都可能需要所有代码来帮助您更远。如果以前的解释测试中没有提供足够的信息,请考虑使用您的代码暂时添加GitHub存储库,并在可能的情况下进行一些测试环境凭据。
Working example
I start this answer with a working example. There are two things you can check as explained in this answer. Please update your question with extra information/ details when parts of the answer fit your situation.
Add this code to
tests/TwilioTest.php
:Result
Execute the tests:
Please verify if this code is working for you also. If not, please tell me what composer library versions you use. Consider adding this info to your question
composer show -i
.The result should be:
I expect you somehow call
retrieveLastTextFromBot
on something else than themock
objectIf the code above is working, I suspect you somehow call the method
retrieveLastTextFromBot
on the production code, instead of the mock object or you might execute the method twice from a different location.To find out what is really happening add the following code to
retrieveLastTextFromBot
(in your production code):If it returns the file where the
SUT
(System under test) is located, you now know for sure you don't have executed the method on the mock object. You might see a different file, in that case, check your code to see from where you execute it.Check your tests to see what instance is passed in the constructor. If otherwise, let me know what the result of the
debug_backtrace()
is and consider updating your question with the results so we can continue to help, since not all code is provided it might be needed to help your further.If non of the previous explained tests gave you enough information, please consider adding a temporarily github repository with your code and maybe if possible some test environment credentials.