Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect Code Coverage Report? #1044

Open
aldobarr opened this issue Aug 22, 2024 · 3 comments
Open

Incorrect Code Coverage Report? #1044

aldobarr opened this issue Aug 22, 2024 · 3 comments

Comments

@aldobarr
Copy link

aldobarr commented Aug 22, 2024

Q A
php-code-coverage version 11.0.6
PHP version 8.3.7
Driver Xdebug
Xdebug version (if used) 3.3.2-1
Installation Method Composer
Usage Method PHPUnit
PHPUnit version (if used) 11.3.1

I'm currently using Laravel v11.21.0. In it I have a service which interacts with an API using Laravel's Http Facade. Here's the code:

<?php

declare(strict_types=1);

namespace App\Services;

use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Http;
use Psr\Http\Message\ResponseInterface;

class ApiService
{
    private PendingRequest $client;
    private const RETRY_ATTEMPTS = 3;

    public function __construct(private readonly string $baseUrl, private readonly string $apiToken)
    {
        $this->resetClient();
    }

    protected function resetClient(): void
    {
        $this->client = Http::baseUrl($this->baseUrl)
            ->retry(self::RETRY_ATTEMPTS, $this->getRetryDelay(...))
            ->withResponseMiddleware(function (ResponseInterface $response) {
                $this->resetClient();
                return $response;
            })->withHeader('api-key', $this->apiToken)->acceptJson();
    }

    public function getRetryDelay(int $attempt, \Exception $exception): int
    {
        return pow(2, $attempt - 1) * 100;
    }

    public function createCustomer($data): object
    {
        $response = $this->client->post('v1/endpoint', [
            'data' => $data
        ])->throw();

        $response_object = $response->object();
        if ($response_object->result !== 'success') {
            throw new RequestException($response);
        }

        return $response_object->data;
    }
}

For whatever reason this API will respond with 200 status codes sometimes even when invalid data is sent... Anyway, I have this unit test for covering that case:

    #[Test]
    public function error_response_with_200_status(): void
    {
        $url = 'https://example.com';
        $key = 'api-key';

        Http::preventStrayRequests();
        Http::fake([
            $url . 'v1/endpoint' =>
                Http::response(json_encode(['result' => 'error', 'data' => (object)[]]), Response::HTTP_OK)
        ]);

        $this->expectException(RequestException::class);
        $apiService = new ApiService($url, $key);
        $apiService->createCustomer([]);
    }

I've stepped through this code and confirmed 100% that the line within the result !== 'success' if statement is executed. Yet here's a code coverage report for the ApiService:

image

I also tested this with PCOV v1.0.11-5 and got the same results...

@sebastianbergmann
Copy link
Owner

Thank you for your report.

Please provide a minimal, self-contained, reproducing test case that shows the problem you are reporting.

Without such a minimal, self-contained, reproducing test case I will not be able to investigate this issue.

@aldobarr
Copy link
Author

Thank you for your report.

Please provide a minimal, self-contained, reproducing test case that shows the problem you are reporting.

Without such a minimal, self-contained, reproducing test case I will not be able to investigate this issue.

I did, see above.

@sebastianbergmann
Copy link
Owner

The example you provided is neither minimal nor self-contained.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants