标签: phpunit

Laravel Mock 应该至少被调用一次但被调用了 0 次

我有一个 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)

php phpunit laravel mockery laravel-6

3
推荐指数
1
解决办法
3939
查看次数

PHPUnit:如何提交原始数据以发布请求链接以在 Lumen 中进行测试?

我使用的是 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。)

php phpunit unit-testing laravel lumen

3
推荐指数
1
解决办法
2420
查看次数

如何在 phpunit 测试中使用带有模拟缓存的缓存标签?

我已经在 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'

有人知道吗?多谢 :)

phpunit caching mocking laravel

3
推荐指数
1
解决办法
1156
查看次数

Pphunit 不断给出错误:[1049] 未知数据库 ':memory:'

我刚刚开始在 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)

mysql phpunit laravel

3
推荐指数
1
解决办法
1885
查看次数

Laravel 7 单元测试到注册路由重定向到主页

我正在使用提供的几乎完全开箱即用的注册流程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()可以看到验证器已运行并列出了错误。

php phpunit unit-testing laravel-7

3
推荐指数
1
解决办法
1012
查看次数

Laravel:如何向第 3 方伪造 http 请求并模拟 json 响应

我正在努力弄清楚什么可能是非常基本的东西,我会被嘲笑离开这里,但我希望也许它也能对其他人有所帮助。

我正在尝试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)

testing phpunit laravel laravel-7

3
推荐指数
1
解决办法
1万
查看次数

Laravel 8 测试:PHPUnit 错误:未知格式化程序“唯一”

我编写了一个涉及工厂的测试。当我执行测试时,我收到此错误:

为 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)

phpunit laravel

3
推荐指数
1
解决办法
4315
查看次数

Symfony 如何加载端到端测试的测试环境?

我正在开发另一个使用端到端测试和.env文件的 PHP 项目。但是,在运行测试之前,我需要修改.env文件以指向测试数据库(而不是开发数据库)。当我从事 Symfony 项目时,我认为我不需要这样做,它只是自动加载测试环境。

我从以前使用旧版本的一些经验知道,每个环境曾经有一个不同的前端控制器,例如app.phpapp_dev.php等等,但据我所知,现在情况并非如此。

Symfony 如何知道加载测试环境以进行端到端测试?

php phpunit symfony

3
推荐指数
1
解决办法
3966
查看次数

Mock_Response::getBody() 的返回值必须是 Psr\Http\Message\StreamInterface 的实例,在 PHPUnit 9.5.10 测试中返回的字符串

我最近在我的 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)

php phpunit unit-testing mocking guzzle

3
推荐指数
1
解决办法
1661
查看次数

Symfony PHPUnit:无法启动会话,因为标头已发送

版本:

  • PHP:8.1
  • PHP 单元:9.5.21
  • 交响乐6.1

当 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 &quot;C:\Users\cimba\Documents\project\vendor\phpunit\phpunit\src\Util\Printer.php&quot; 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)

php phpunit symfony php-8.1 symfony6

3
推荐指数
1
解决办法
2999
查看次数