我正在嘲笑一个类的函数,并尝试根据给定对象(该模拟函数的参数)作为属性返回不同的值。
在我的代码下面,有一些评论:
代码
use AppBundle\Entity\Campaign;
use Monolog\Logger;
use PHPUnit\Framework\TestCase;
class FacebookHelperTest extends TestCase {
public function testIfStatusSyncIsSetCorrectly() {
$campaign = new Campaign();
/** @var \PHPUnit_Framework_MockObject_MockObject|Logger $logger */
$logger = $this->createMock(Logger::class);
/** @var \PHPUnit_Framework_MockObject_MockObject|FacebookHelper $helper */
$builder = $this->getMockBuilder(FacebookHelper::class)->disableOriginalConstructor()->setMethods(['getExternalCampaignData']);
$helper = $builder->getMock();
$helper->expects($this->exactly(3))
->method('getExternalCampaignData')
->withConsecutive(
[$this->callback(function(Campaign $campaign) { var_dump($campaign->getFbCampaignId(), "expecting 1"); return $campaign->getFbCampaignId() == 1; })],
[$this->callback(function(Campaign $campaign) { var_dump($campaign->getFbCampaignId(), "expecting 2"); return $campaign->getFbCampaignId() == 2; })],
[$this->callback(function(Campaign $campaign) { var_dump($campaign->getFbCampaignId(), "expecting 3"); return $campaign->getFbCampaignId() == 3; })]
)
->willReturnOnConsecutiveCalls(
['campaign' => ['status' => FacebookHelper::CAMPAIGN_STATUS_ACTIVE]],
['campaign' => ['status' => FacebookHelper::CAMPAIGN_STATUS_ACTIVE]],
['campaign' => ['status' => FacebookHelper::CAMPAIGN_STATUS_ARCHIVED]]
);
$campaign->setFbCampaignId(1);
$campaign->setStatus('active');
$modifiedCampaign = $helper->modifyCampaignIfNeeded($campaign, $logger);
$this->assertFalse($modifiedCampaign->getSettings('fb_status_out_of_sync'));
$campaign->setFbCampaignId(2);
$campaign->setStatus('paused');
$modifiedCampaign = $helper->modifyCampaignIfNeeded($campaign, $logger);
$this->assertTrue($modifiedCampaign->getSettings('fb_status_out_of_sync'));
$campaign->setFbCampaignId(3);
$campaign->setStatus('paused');
$modifiedCampaign = $helper->modifyCampaignIfNeeded($campaign, $logger);
$this->assertTrue($modifiedCampaign->getSettings('fb_status_out_of_sync'));
}
}
当我进行上述单元测试时,一切似乎都正常。 除了某种行为有点奇怪之外,回调被调用了太多次。
我已经发现了一个可能导致这种情况的错误:https://github.com/sebastianbergmann/phpunit-mock-objects/issues/261 因此我将phpunit更新到5.7.20版本以希望此问题得到修复
或许我需要使用不同的方法?
PHPunit的结果
Testing started at 10:40 AM ...
Nothing to update - your database is already in sync with the current entity metadata.
PHPUnit 5.7.20 by Sebastian Bergmann and contributors.
Expectation failed for method name is equal to <string:getExternalCampaignData> when invoked 3 time(s)
Parameter 0 for invocation #0 AppBundle\Services\FacebookHelper::getExternalCampaignData(AppBundle\Entity\Campaign Object (...)) does not match expected value.
Failed asserting that AppBundle\Entity\Campaign Object &0000000026aee99e00000000359c8973 (
...
'status' => 'paused'
...
'fb_campaign_id' => 2
...
'settings' => Array &1 (
'fb_status_out_of_sync' => false
)
...
) is accepted by specified callback.
/home/ali/www/src/AppBundle/Services/FacebookHelper.php:1227
/home/ali/www/tests/AppBundle/Services/FacebookHelperTest.php:41
int(1)
string(11) "expecting 1"
int(1)
string(11) "expecting 1"
int(2)
string(11) "expecting 2"
int(2)
string(11) "expecting 1"
Time: 702 ms, Memory: 6.00MB
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
Process finished with exit code 1
答案 0 :(得分:0)
Oke,经过大量的搜索,我检查了phpunit测试本身的单元测试(悖论:p?),最后发现它是如何工作的。
解决方案
$helper->expects($this->exactly(3))
->method('getExternalCampaignData')
->will(
$this->returnCallback(
function(Campaign $campaign) {
if($campaign->getFbCampaignId() == 1) return ['campaign' => ['status' => FacebookHelper::CAMPAIGN_STATUS_ACTIVE]];
if($campaign->getFbCampaignId() == 2) return ['campaign' => ['status' => FacebookHelper::CAMPAIGN_STATUS_ACTIVE]];
if($campaign->getFbCampaignId() == 3) return ['campaign' => ['status' => FacebookHelper::CAMPAIGN_STATUS_ARCHIVED]];
}
)
);
答案 1 :(得分:0)
您可以将此简化为
# set the initial size
from kivy.config import Config
MAX_SIZE = (300, 150)
Config.set('graphics', 'width', MAX_SIZE[0])
Config.set('graphics', 'height', MAX_SIZE[1])
from kivy.app import App
from kivy.uix.button import Button
from kivy.core.window import Window
class My(App):
def check_resize(self, instance, x, y):
# resize X
if x > MAX_SIZE[0]:
Window.size = (300, Window.size[1])
# resize Y
if y > MAX_SIZE[1]:
Window.size = (Window.size[0], 150)
def build(self):
Window.bind(on_resize=self.check_resize)
return Button()
My().run()