标签: phpunit

Laravel - 数据库事务 - 超出锁定等待超时

我们使用 DatabaseTransactions 特征和 MySQL 数据库连接执行单元测试(很多)。

当执行完整的测试套件时,我们得到 15 条左右的“常规错误:1205 超出锁定等待超时;”。当单独执行这些测试时,它们都成功了。

问题主要出现在执行sync()方法时,但不仅限于此。

(尝试增加等待超时,但没有成功)。

任何建议将不胜感激。

也发布在 laracasts 中:https://laracasts.com/discuss/channels/testing/test-suite-general-error-1205-lock-wait-timeout-exceeded

mysql phpunit transactions database-deadlocks laravel

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

如何让单元测试忽略 Laravel 中的中间件

我正在 Laravel 应用程序中测试端点。但是,我有一个中间件,它执行复杂的逻辑来确定用户的位置(使用 ip 反向查找等,例如以下代码:

public function getOpCityByIP()
{
    // Get the client's remote ip address
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR']) {
        $clientIpAddress = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0];
    } else {
       $clientIpAddress = $_SERVER['REMOTE_ADDR'];
    }
    $opCityArray = OpCityIP::get($clientIpAddress);
    return $opCityArray;
}
Run Code Online (Sandbox Code Playgroud)

我对深入所述中间件中此类方法的内部并不得不模拟它们等不感兴趣。我宁愿在单元测试期间简单地跳过整个中间件,或者至少模拟其整个操作,并将结果硬编码为预定的东西。我怎么做?

我正在使用 Laravel 5.4

更新

我需要它忽略特定的中间件,而不是全部

phpunit laravel mockery laravel-5

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

模拟 Laravel 命令依赖项

正如 Laravel 官方文档所述,我执行了以下命令:

namespace App\Console\Commands;

use App\Model\Report;
use Illuminate\Console\Command;
use Exception;

class ExportAnualReport extends Command
{
    /**
     * @var string
     */
    protected $description = "Print Anual Report";

    /**
     * @var string
     */
    protected $signature = "report:anual";

    public function __construct()
    {
        parent::__construct();
    }

    public function handle(Report $report): int
    {
        //@todo Implement Upload
        try {
            $reportData = $report->getAnualReport();
            $this->table($reportData['headers'], $reportData['data']);
            return 0;
        } catch (Exception $e) {
            $this->error($e->getMessage());
            return 1;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但我已经遵循了 Laravel 的方法和建议,而不是这个问题中使用的方法 ,并且利用依赖注入来将我的模型作为服务插入。

所以我同时认为对它进行单元测试是一个好主意: …

php phpunit command laravel laravel-5.7

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

PHPUnit - 为 foreach() 提供的无效参数尽管预期但未被识别

一切......我的主题说明了一切。我正在尝试进行一个测试,实际上故意使“为 foreach() 提供的参数无效”发生。我试图让 PHPUnit 期待,但是......不,我的测试仍然突然停止。原因是:“为 foreach() 提供的参数无效”,就在我告诉它它将发生的确切位置。

在我的文件顶部有:

use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Error\Error;
use PHPUnit\Framework\Error\Notice;
use PHPUnit\Framework\Error\Warning;
Run Code Online (Sandbox Code Playgroud)

我的班级声明开头为:

Class flirzelkwerpTest extends TestCase {
Run Code Online (Sandbox Code Playgroud)

以下是测试文件中的行:

    // Let's try to add nothing.
    // (It should throw an error because of "Invalid argument supplied for foreach()" in barabajagal.php.)
    $this->expectException(\InvalidArgumentException::class);
    $this->expectExceptionMessage('Invalid argument supplied for foreach()');
    $resp = $barabajagal->add();
Run Code Online (Sandbox Code Playgroud)

错误发生在最后一行。前两行不应该告诉 PHPUnit,“嘿,小伙子,我预计这里会出现错误,这是您应该逐字得到的消息”?

我们使用 PHP 7.3.4 和 PHPUnit 8.3.2。

phpunit invalidargumentexception

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

模拟 Laravel 自定义验证规则类不起作用

我正在表单提交中实施新的自定义验证规则。但我想绕过单元测试中的验证规则。下面是验证规则和单元测试类的简化。我缺少什么?

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class Captcha implements Rule
{
    public function passes($attribute, $value)
    {
        // assuming will always return false in testing
        // works fine when true
        return false; 
    }

    public function message()
    {
        return 'Captcha error! Try again later or contact site admin.';
    }
}
Run Code Online (Sandbox Code Playgroud)
use Tests\TestCase;
use App\Rules\Captcha;

class RegistrationTest extends TestCase {

    public test_user_registration()
    {
        $this->mock(Captcha::class, function ($mock) {
            $mock->shouldReceive('passes')->andReturn(true);
        });

        $response = $this->post(route('tenant.register'), [
            'g-recaptcha-response' => 1,
            'email' => 'user@example.com',
            'password' => 'secret',
        ]);

        $this->assertEquals(1, …
Run Code Online (Sandbox Code Playgroud)

phpunit laravel-5

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

如何使用 PhpUnit 在 Laravel 中仅模拟一种方法

我有这个测试:

<?php

namespace Tests\Feature;

use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\Services\AccessTokenService;
use App\Services\MemberService;

class BranchTest extends TestCase    

public function testPostBranchWithoutErrors()
    {
        $this->mock(AccessTokenService::class, function ($mock) {
            $mock->shouldReceive('introspectToken')->andReturn('introspection OK');
        });

        $this->mock(MemberService::class, function ($mock) {
            $mock->shouldReceive('getMemberRolesFromLdap')->andReturn(self::MOCKED_ROLES);
        });
Run Code Online (Sandbox Code Playgroud)

如您所见,此测试有 2 个模拟。第二个“MemberService:class”是我当前的问题。此类中有 2 个函数:“createMember”和“getMemberRolesFromLdap”。我精确地说,我只想模拟“getMemberRolesFromLdap”函数。

在文档中,写道:

当你只需要模拟一个对象的几个方法时,可以使用partialMock方法。未被mock的方法在调用时会正常执行:

$this->partialMock(Service::class, function ($mock) { $mock->shouldReceive('process')->once(); });

但是当我使用“partialMock”时,出现以下错误:

错误:调用未定义的方法 Tests\Feature\BranchTest::partialMock()

当我尝试经典模拟(无部分)时,出现以下错误:

收到 Mockery_1_App_Services_MemberService::createMember(),但未指定期望

当然是因为这个类中有 2 个函数,所以 PhpUnit 不知道如何处理函数“createMember”。

接下来我可以尝试什么?我是 PhpUnit 测试的初学者。

编辑

Laravel 6.0
PHPUnit 7.5

phpunit laravel mockery

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

Laravel CRUD 应用程序 Dusk 与 PHPUnit

我目前正在开发 Laravel CRUD 应用程序,我想知道为什么 PHPUnit 不支持抓取浏览器(正如我所读到的)。我已经通过 PHPUnit 覆盖了我的项目的基础,但我也想测试链接、标签、按钮点击等。所以我已经有了一个强大的单元测试基础。

现在我读到 Dusk 为 DOM 测试提供了一个爬虫。我应该一起使用两者吗(甚至可能吗?)还是应该迁移到 Dusk?我不确定 Dusk 是否提供与 PHPUnit 相同的功能,并且如上所述,我确实已经拥有强大的 phpunit 测试基础。

从现在开始,由于 50:50 的测试用例,我有点陷入困境,因为我还需要测试 DOM 是否提供了正确的信息。

感谢任何帮助或专家建议。

先感谢您!

phpunit crud laravel laravel-dusk

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

Laravel 7:assertSee() 和 html 实体

在我的测试中,我使用assertSee()。

    $message = '<h1>Header</h1>';
    $response = $this->get($url);
    $response->assertStatus(200);
    $response->assertSee($message);
Run Code Online (Sandbox Code Playgroud)

问题是,当$message包含 html 实体时,断言将变为 false。

我知道有一个e()帮助程序可以在 $message 中转换 html 实体,但现在我需要相反的。

我该怎么做?

phpunit laravel-7

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

如何在测试代码时完全覆盖条件(例如 PHP 和 xdebug)

不久前,我开始在 PHPUnit (v. 9) 中编写测试。这很棒而且令人惊奇,但是:

如何正确涵盖条件语句?

我将给出一些例子,其中结果是正确的和预期的,以及我发现问题的地方。这里是:

请注意,下面的代码只是示例。

我知道当我传递trueif语句时,将没有机会转到代码的其他分支。这只是尽可能简单的示例。

问题不存在的情况:

if (true) {
    return 'true';//here is covered
}
return 'false';//here is not covered    
Run Code Online (Sandbox Code Playgroud)

这没关系,但是如下:

return (true) ? 'true' : 'false';
Run Code Online (Sandbox Code Playgroud)

整行被视为覆盖,但显然 false 永远不会返回。

所以。我做什么坏事了?

唯一的解决方案是不使用三元运算符?它的语法非常短,但由于缺乏有关覆盖率的(真实/错误)信息而容易出错。:(

php phpunit code-coverage xdebug

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

使用 pest 在自定义测试套件中进行测试时,获取 InvalidArgumentException - laravel 中 fakerphp/faker 库的未知格式

我正在使用Pest库在 laravel 中编写测试。我my-laravel-application/tests/Integration在 laravel 中创建了目录并在中定义了一个新的测试套件phpunit.xml

<testsuite name="Integration">
   <directory suffix=".test.php">./tests/Integration</directory>
</testsuite>
Run Code Online (Sandbox Code Playgroud)

这样 Laravel 就会承认 Integration 目录中的测试文件,并且我可以在具有正确名称的单独目录(Integration 目录)中编写集成测试,并且我将测试文件放入该目录中my-laravel-application/tests/Integration,在运行时出现以下错误php artisan test

InvalidArgumentException - Unknown format "name"
vendor/fakerphp/faker/src/Faker/Generator.php:657
Run Code Online (Sandbox Code Playgroud)

这表明$this->faker->name()我的代码行UserFactory(我在测试中使用 UserFactory 类)有问题,它说 $this->faker 上不存在 name() 方法。但在将它们移动到目录之前,我的测试曾经运行良好my-laravel-application/tests/Integration。真正的问题是什么?我该如何解决这个问题?

php phpunit laravel pestphp

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