我有一个 artisan 命令,它触发一个名为PasswordResetJob的作业,该作业在调用存储库类OrgRepository中的ForcePasswordReset方法时进行迭代,该方法更新用户的表。整个过程运行良好。
现在,我尝试编写一个 Laravel 测试来模拟OrgRepository类,并断言强制密码重置方法至少被调用一次,根据我提供给测试的条件,情况应该是这样。在测试中,我调用artisan命令来解雇工作;(我正在使用同步队列进行测试)当作业被调用并且用户的表被更新时,这工作得很好,因为我可以直接查看数据库更新。但是,测试失败并出现错误:Mockery\Exception\InvalidCountException:Mockery_2_Repositories_OrgRepository 中的方法forcePasswordReset() 应该至少调用 1 次,但调用了 0 次。
测试中的工匠调用是:
Artisan::call('shisiah:implement-org-password-reset');
Run Code Online (Sandbox Code Playgroud)
我之前和模拟初始化之后都尝试过进行 artisan 调用,但仍然遇到相同的错误。这是测试中的模拟初始化
$this->spy(OrgRepository::class, function ($mock) {
$mock->shouldHaveReceived('forcePasswordReset');
});
Run Code Online (Sandbox Code Playgroud)
我缺少什么?我已经阅读了文档并通过谷歌搜索了几个小时。如果您需要任何其他信息来帮助,请告诉我。我使用的是Laravel 6.0 版本
我将OrgRepository类传递给作业类的handle方法,如下所示:
public function handle(OrgRepository $repository)
{
//get orgs
$orgs = Org::where('status', true)->get();
foreach ($orgs as $org){
$repository->forcePasswordReset($org);
}
}
Run Code Online (Sandbox Code Playgroud) 我使用的是 Lumen 附带的默认 PHPUnit。虽然我能够创建对链接的模拟后调用,但我无法找到向其提供原始数据的方法。
目前,为了模拟 JSON 输入,从官方文档中,我可以:
$this->json('POST', '/user', ['name' => 'Sally'])
->seeJson([
'created' => true,
]);
Run Code Online (Sandbox Code Playgroud)
或者,如果我想要简单的表单输入,我可以:
$this->post('/user', ['name' => 'Sally'])
->seeJsonEquals([
'created' => true,
]);
Run Code Online (Sandbox Code Playgroud)
有没有办法将原始正文内容插入到发布请求中?(或者至少是一个带有XML输入的请求?这是一个从微信接收回调的服务器,我们别无选择,只能按照微信想要使用的方式使用XML。)
我已经在 Laravel 项目上实现了缓存标签,并且我的控制器中有类似的内容:
if (Cache::tags(['api'])->has('someKey')) {
return new JsonResponse(Cache::tags(['api'])->get('someKey'));
}
Run Code Online (Sandbox Code Playgroud)
我想编写一个 phpunit 测试来测试这段代码:我模拟了 Laravel 文档中的缓存,但我还没有找到任何关于如何tags在模拟缓存上使用的内容
我试过 :
Cache::tags(['api'])->shouldReceive('has')->with('someKey')->andReturn(true)->once();
Run Code Online (Sandbox Code Playgroud)
或者
Cache::shouldReceive('has')->tags(['api'])->with('someKey')->andReturn(true)->once();
Run Code Online (Sandbox Code Playgroud)
但这都不起作用,我得到了Call to undefined method Illuminate\Cache\ArrayStore::shouldReceive()或
call_user_func_array() expects parameter 1 to be a valid callback, class 'Mockery\Expectation' does not have a method 'tags'
有人知道吗?多谢 :)
我刚刚开始在 Laravel 7 中使用 phpunit。我遇到了一个无法找到解决方案的问题。我正在使用 Laravel 7 和 Xampp。
My phpunit.xml:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpcd ..
cdit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
>
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
</whitelist>
</filter>
<php>
<server name="APP_ENV" value="testing"/>
<server name="BCRYPT_ROUNDS" value="4"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="DB_CONNECTION" value="mysql"/>
<server name="DB_DATABASE" value=":memory:"/>
<server name="MAIL_MAILER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>
<server name="SESSION_DRIVER" value="array"/>
<server name="TELESCOPE_ENABLED" value="false"/>
</php>
</phpunit>
Run Code Online (Sandbox Code Playgroud)
我的测试功能:
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Tests\TestCase;
class …Run Code Online (Sandbox Code Playgroud) 我正在使用提供的几乎完全开箱即用的注册流程Laravel 7。
当我尝试通过网络浏览器中的表单提交无效的注册表单时,我会返回到注册页面,其中包含错误列表,这正是我期望发生的情况。
但是,我正在尝试为此功能编写一个单元测试,但由于某种原因,当我在单元测试中发出相同的请求时,我得到了重定向到 root page 的响应/。
为什么我的单元测试没有返回与通过浏览器发出相同请求时相同的 HTML 响应?我怀疑这可能是由于请求中缺少发送的 CSRF 令牌,但根据文档,CSRF 中间件应该在单元测试期间被禁用。
运行测试时,CSRF 中间件会自动禁用。
这是我的单元测试代码:
public function testPostInvalidRegistration(){
$response = $this->post("/register",[
'first_name' => $this->faker->name
]);
$response->dumpSession();
$response->dump();
$response->dumpHeaders();
}
Run Code Online (Sandbox Code Playgroud)
这是输出$response->dump()
public function testPostInvalidRegistration(){
$response = $this->post("/register",[
'first_name' => $this->faker->name
]);
$response->dumpSession();
$response->dump();
$response->dumpHeaders();
}
Run Code Online (Sandbox Code Playgroud)
我$response->dumpSession()可以看到验证器已运行并列出了错误。
我正在努力弄清楚什么可能是非常基本的东西,我会被嘲笑离开这里,但我希望也许它也能对其他人有所帮助。
我正在尝试Http在功能测试中模拟/测试请求。我仍在学习好的/更好/最好的测试技术,所以也许有更好的方法。
// MyFeatureTest.php
$user = factory(User::class)->create(['email' => 'example@email.com']);
// Prevent actual request(s) from being made.
Http::fake();
$this->actingAs($user, 'api')
->getJson('api/v1/my/endpoint/123456')
->assertStatus(200);
Run Code Online (Sandbox Code Playgroud)
在我的控制器中,我的请求如下所示:
public function myFunction() {
try {
$http = Http::withHeaders([
'Accept' => 'application/json',
'Access_Token' => 'my-token',
'Content-Type' => 'application/json',
])
->get('https://www.example.com/third-party-url, [
'foo' => 'bar,
]);
return new MyResource($http->json());
} catch (RequestException $exception) {
Log::error("Exception error: " . print_r($exception, true));
}
}
Run Code Online (Sandbox Code Playgroud)
我想模拟我收到 200 响应,并且理想情况下模拟来自资源的预期 json。当端点位于我的应用程序本地时(不调用第三方),我已经成功地进行了此测试。这就是我过去所做的:
$http->assertStatus(200)
->assertJsonStructure([
'type', 'id', 'attributes' => [
'email', 'uuid', …Run Code Online (Sandbox Code Playgroud) 我编写了一个涉及工厂的测试。当我执行测试时,我收到此错误:
为 Tests\Unit\ExampleTest::testTakePlace 指定的数据提供程序无效。InvalidArgumentException:未知格式化程序“唯一”/var/www/html/api/vendor/fakerphp/faker/src/Faker/Generator.php:249
不应显示此错误,我应该能够使用$this->faker->unique().
通过一遍又一遍地阅读文档(没有发现任何差异)并阅读互联网上的问题和答案(只找到一个问题和一个答案:扩展 Laravel,TestCase但官方文档,正如我提到的,恰恰相反)。(Laravel 的TestCase由 提供use Illuminate\Foundation\Testing\TestCase;)
为什么它不起作用以及如何修复这个错误?
它扩展了PHPUnit\Framework\TestCase(不是 Laravel 的TestCase),因为文档说要扩展它。事实上: https: //laravel.com/docs/8.x/testing#creating-and-running-tests。这并不是文档中提到扩展它的唯一部分。
<?php
namespace Tests\Unit;
use PHPUnit\Framework\TestCase;
use App\Models\Project;
class ExampleTest extends TestCase
{
/**
* @dataProvider provideTakePlaceData
*/
public function testTakePlace($project)
{
$response = $this->json('GET', '/controllerUserProject_takePlace', [
'project_id' => $project->id
]);
}
public function provideTakePlaceData() {
return [
Project::factory()->make()
];
}
}
Run Code Online (Sandbox Code Playgroud)
<?php
namespace App\Http\Controllers;
use …Run Code Online (Sandbox Code Playgroud) 我正在开发另一个使用端到端测试和.env文件的 PHP 项目。但是,在运行测试之前,我需要修改.env文件以指向测试数据库(而不是开发数据库)。当我从事 Symfony 项目时,我认为我不需要这样做,它只是自动加载测试环境。
我从以前使用旧版本的一些经验知道,每个环境曾经有一个不同的前端控制器,例如app.php,app_dev.php等等,但据我所知,现在情况并非如此。
Symfony 如何知道加载测试环境以进行端到端测试?
我最近在我的 Symfony 4 应用程序中升级到 PHPUnit 9.5.10,现在我似乎有一堆与我使用 Guzzle 对端点进行的 HTTP 调用相关的失败测试。
失败的是:
1) Tests\AppBundle\Services\CourseTest::testUpdateAssignedCourseFromKey with data set "valid Course, current refkey" (AppBundle\Entity\Referral Object (...), array(true), AppBundle\Entity\Site Object (...), 'lambda')
TypeError: Return value of Mock_Response_0807f175::getBody() must be an instance of Psr\Http\Message\StreamInterface, string returned
/private/var/www/crmpicco/src/AppBundle/Services/Course.php:250
/private/var/www/crmpicco/src/AppBundle/Services/Course.php:187
/private/var/www/crmpicco/src/AppBundle/Services/Course.php:92
/private/var/www/crmpicco/Tests/AppBundle/Services/CourseTest.php:99
Run Code Online (Sandbox Code Playgroud)
我的测试方法如下所示:
/**
* @dataProvider refkeyProvider
*
* @param Referral $referral
* @param Site $site
* @param $expectedpartner
*
* @internal param Person $person
*/
public function testUpdateAssignedCourseFromKey(Referral $referral, $apiresult, Site $site, $expectedCourse)
{
$apiresult = …Run Code Online (Sandbox Code Playgroud) 版本:
当 PhpUnit 运行以下测试时,我收到有关会话无法启动的错误。有谁知道这个问题以及如何解决它?
以下主题无法回答我的问题,或者建议的解决方案对我不起作用:
我尝试了第二个链接建议的解决方案:@session_start()但@runInSeparateProcess没有任何效果。也许我只是误解了我的问题,但我现在被困了一个星期。
protected function setUp(): void
{
@session_start();
parent::setUp();
}
/**
* @runInSeparateProcess
*/
public function testLoginFailure(): void
{
$client = static::createClient();
$crawler = $client->request('GET', '/login');
$form = $crawler->selectButton('Login')->form();
$form['email']->setValue('bob@gmail.com');
$form['password']->setValue('123abcABC%');
$crawler = $client->submit($form);
$this->assertResponseIsSuccessful();
}
Run Code Online (Sandbox Code Playgroud)
<!-- Failed to start the session because headers have already been sent by "C:\Users\cimba\Documents\project\vendor\phpunit\phpunit\src\Util\Printer.php" at line 104. (500 Internal Server Error) -->
C:\Users\cimba\Documents\project\vendor\symfony\framework-bundle\Test\BrowserKitAssertionsTrait.php:142
C:\Users\cimba\Documents\project\vendor\symfony\framework-bundle\Test\BrowserKitAssertionsTrait.php:33
C:\Users\cimba\Documents\project\tests\InternalLoginTest.php:51 …Run Code Online (Sandbox Code Playgroud)