我有一个登录函数,需要从单独的用户服务API调用。
登录的唯一目的是用于测试,因为我需要获取将用作我的一个中间件的参数的承载令牌。
至于测试,是否可以只通过HTTP请求调用外部api一次?如果可以,我应该把它放在哪里?
我在setUp()
函数上尝试过,但似乎每次在测试类上执行测试函数时都会调用它,这使得测试变慢。
- 编辑代码:**
测试代码:
<?php
namespace Tests\Feature\Controllers;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPUnit\Framework\TestSuite;
use Tests\TestCase;
class MyTest extends TestCase
{
protected string $bearerToken;
public function setUp(): void
{
parent::setUp();
$this->bearerToken = self::getToken();
}
protected static function getToken()
{
$response = Http::post('http://auth_api/oauth/token', [
...
...
]);
// but assume that this request always succeed.
if ($response->failed()) return [];
return json_decode(json_encode($response->json()), true)['access_token'];
}
...test methods here
}
我还尝试过手动标记,这样在整个测试套件中定制登录函数只会被获取一次。
如下所示:
protected static $isInitiated = false;
protected string $bearerToken;
public function setUp(): void
{
parent::setUp();
if (! self::$isInitiated) {
$this->bearerToken = self::getToken();
self::$isInitiated = true;
}
}
根据这里的答案
但它让我错误地说:
$bearerToken must not be accessed before initialization
因此,根据该错误,测试方法必须在它为$bearerToken赋值之前就已经执行了。
我还尝试了public static function setUpBeforeClass()
:
protected static ?string $bearerToken = null;
public static function setUpBeforeClass(): void
{
self::$bearerToken = self::getToken();
}
但它也给我错误的说法:
A facade root has not been set.
有什么办法可以做到吗?
1条答案
按热度按时间toe950271#
您不应该在测试中调用任何外部API,原因很简单,您正在测试您或您的团队编写的应用程序,而不是其他人。
因此,您应该模拟所有外部部件,例如使用
Http::fake()
。以下是文档:https://laravel.com/docs/9.x/http-client#faking-responses
而如果你真的想调用外部API,新建一个GuzzleClient,那么你就可以做你想做的事情,但是你应该意识到那不是一个好主意。