PHPUnit模拟了一个类方法,以在api调用后返回特定值

时间:2019-05-30 15:32:58

标签: php laravel testing mocking phpunit

在进行api调用之后,我正在Laravel 5.8中编写一个测试,以检查是否创建了一些数据库记录并且存在关系等。

api调用在类上运行一个方法,该方法对现实世界中需要的外部服务进行自己的api调用,但是我在测试中并不关心它。

我想模拟该类/方法,以便它返回某个值,这样我就可以在测试中忘记它。

下面是我的测试,我试图模拟PayPointAdapter类,尤其是makePayment方法。

/** @test */
    public function client_can_make_a_payment()
    {
        $client = factory(Client::class)->create();
        $invoice = factory(Invoice::class)->create([
            'client_id' => $client->id
        ]);
        $card = factory(PaymentCard::class)->make([
            'client_id' => $client->id
        ]);

        $this->assertCount(0, $client->payments);
        $this->assertCount(0, $client->paymentCards);

        $mock = \Mockery::Mock(PayPointAdapter::class)
            ->allows(['makePayment' => ["status" => "success", "transid" => 123]]);

        $response = $this->json(
            'POST',
            '/api/payments',
            [
                'invoiceid'                 => $invoice->id,
                'amount'                    => $invoice->total(),
                'clientdetails-firstname'   => $client->first_name,
                'clientdetails-lastname'    => $client->last_name,
                'clientdetails-email'       => $client->email,
                'clientdetails-address1'    => $client->address_line_one,
                'clientdetails-address2'    => $client->address_line_two,
                'clientdetails-city'        => $client->city,
                'clientdetails-state'       => $client->state,
                'clientdetails-postcode'    => $client->postcode,
                'clientdetails-phonenumber' => '',

                'cardtype'     => $card->type,
                'cardnum'      => $card->number,
                'cardexp'      => $card->expiry,
                'cardstart'    => $card->start,
                'cardissuenum' => $card->issue,
                'cccvv'        => $card->ccv
            ]
        );

        $response->assertStatus(201);
        $client->refresh();
        $invoice->refresh();
        $this->assertCount(1, $client->paymemnts);
        $this->assertCount(1, $client->paymentCards);
        $this->assertDatabaseHas('payment_cards', $card->toArray());
        $this->assertTrue($invoice->isPaid());
    }

这是控制器中处理api调用的方法

/**
     * Make a payment.
     *
     * @param \Illuminate\Http\Request $request
     *
     * @return bool
     */
    public function store(Request $request)
    {
        try {
            $payment = $this->payPointAdapter->makePayment($request->all());

            $card = PaymentCard::where('type', request('cardtype'))
                ->where('expiry', request('cardexp'))
                ->where('start', request('cardstart'))
                ->where('ccv', request('cccvv'))
                ->get()
                ->filter(function ($paymentCard) {
                    return $paymentCard->number == request('cardnum');
                });

            if (!$card) {
                $card = PaymentCard::create([
                    'number' => request('cardnum'),
                    'type'   => request('cardtype'),
                    'expiry' => request('cardexp'),
                    'start'  => request('cardstart'),
                    'issue'  => request('cardissuenum')
                ]);
            }

            Payment::create([
                'invoice_id'      => request('invoiceid'),
                'amount'          => request('amount'),
                'payment_method'  => request('payment_method'),
                'payment_card_id' => $card->id,
                'reference'       => $payment['transid']
            ]);

            return response($payment, 201);
        } catch (\Exception $ex) {
            return response($ex->getMessage(), 500);
        }
    }

所以我只想忽略对方法$this->payPointAdapter->makePayment($request->all());的调用,并进行测试以模拟对此方法的响应。

在我的测试中,我创建的模拟并不会阻止其运行该方法。有什么想法吗?

0 个答案:

没有答案