PHPUnit测试用例因未定义索引而随机失败,并尝试获取非对象的属性

时间:2019-06-06 14:28:57

标签: php laravel phpunit

我的PHP / Laravel应用中的一个测试用例随机失败。看起来它有自己的生活。

测试用例失败,并出现以下错误:

Undefined index: impressions

Trying to get property 'ad' of non-object

测试文件:

    class AdReportController extends Controller
{
    /** @var CampaignGroupRepository */
    private $campaignGroupRepo;

    /** @var AdWordsAccountRepository */
    private $adWordsAccountRepo;

    /** @var AdReportRepository */
    private $adReportRepo;

    public function __construct(
        CampaignGroupRepository $campaignGroupRepo,
        AdWordsAccountRepository $adWordsAccountRepo,
        AdReportRepository $adReportRepo
    ) {
        $this->campaignGroupRepo  = $campaignGroupRepo;
        $this->adReportRepo       = $adReportRepo;
        $this->adWordsAccountRepo = $adWordsAccountRepo;

        $this->setTransformer(new AdReportTransformer());
    }

    public function top(AdReportsRequest $request, int $accountId): JsonResponse
    {
        $campaignGroup = $request->input('campaign_group');
        $dateFrom      = $request->input('from');
        $dateTo        = $request->input('to');

        $adWordsAccount = $this->adWordsAccountRepo->findOrFailByGoogleId($accountId);
        $campaignGroup  = $this->campaignGroupRepo->findOrFail($campaignGroup, $adWordsAccount);

        $report = $this->adReportRepo->top($campaignGroup, $dateFrom, $dateTo);

        return $this->response($report);
    }
}

展示错误的测试用例:

public function testIgnoreReportsFromOtherCampaignGroups(): void
{
    [$account, $campaignGroup, $ad] = $this->createEverything();

    $top = $this->createAdReport([
        'date'             => '2019-01-01',
        'ad'               => $ad,
        'impressions'      => 100,
        'clickThroughRate' => 100,
    ]);

    [, , $ad2] = $this->createEverything($account);

    $this->createAdReport([
        'date'             => '2019-01-01',
        'ad'               => $ad2,
        'impressions'      => 300,
        'clickThroughRate' => 150,
    ]);

    $params = http_build_query([
        'campaign_group' => $campaignGroup->id,
        'from'           => '2018-12-30',
        'to'             => '2019-01-06',
    ]);

    $remote = $this->callIt($account, $params)->json();

    $this->assertSame($remote['impressions'], $top->impressions);
}

另一个错误的测试案例:

public function testIgnoreReportsFromOtherAccounts(): void
    {
        [$account, $campaignGroup, $ad] = $this->createEverything();

        $top = $this->createAdReport([
            'date'             => '2019-01-01',
            'ad'               => $ad,
            'impressions'      => 100,
            'clickThroughRate' => 100,
        ]);

        [, , $ad2] = $this->createEverything();

        $this->createAdReport([
            'date'             => '2019-01-01',
            'ad'               => $ad2,
            'impressions'      => 300,
            'clickThroughRate' => 150,
        ]);

        $params = http_build_query([
            'campaign_group' => $campaignGroup->id,
            'from'           => '2018-12-30',
            'to'             => '2019-01-06',
        ]);

        $remote = $this->callIt($account, $params)->json();

        $this->assertSame($remote['impressions'], $top->impressions);
    }

无法弄清楚为什么这些测试会失败并且是随机的。我可以运行20次,不失败然后失败。

1 个答案:

答案 0 :(得分:0)

我正在写对别人可能有用的东西。 问题在于该方法随机生成了一些具有特定索引的广告报告。但是从最后一次提交以来,这些值已更改,因此当生成的随机报告低于索引5或更高时,会导致问题。

解决方案是添加'clicks' => 10,并如下所示:

$top = $this->createAdReport([
            'date'             => '2019-01-01',
            'ad'               => $ad,
            'impressions'      => 100,
            'clickThroughRate' => 20,
            'clicks'           => 10,
        ]);