phpunit 在测试中设置一些默认配置值的最佳实践是什么?
我正在考虑类似的价值观
通常我会使用构造函数或一些设置器来设置它,但当我只有这样的类时我不知道如何做到这一点
class RestTest extends PHPUnit_Framework_TestCase {
Run Code Online (Sandbox Code Playgroud)
例如,我正在尝试为 REST 和 SOAP 服务制作测试用例。
我需要指定 url/用户并通过,但它们在开发/测试/生产时发生变化,因此我需要一种干净的方法来指定它们。
我正在编写一个 MVC 框架,它利用一个库来帮助管理输入变量(例如 get、post 等)。
现在,我正在通过分别将 POST 和 GET 变量的值强制写入 $_POST 和 $_GET 超全局变量来测试 POST 和 GET 变量,但在测试 PUT 和 DELETE 请求变量时遇到了障碍。
例子:
public function testGET()
{
$_GET['test'] = 'test value';
$get_value = Input::get('test', '[default value]');
assertEquals('test value', $get_value);
}
Run Code Online (Sandbox Code Playgroud)
是否有一个好方法来模拟/模拟这些变量或使用各种可用的方法(特别是 GET、POST、PUT、DELETE)来模拟 HTTP 请求?
我正在使用 XAMPP 1.8.1。我需要用 PHPUnit 编写代码。当我尝试使用命令提示符安装 PEAR 时,收到以下消息:
您安装的是系统范围的 PEAR 还是本地副本?
有人可以建议我应该使用哪个选项吗?提前致谢。
我想用 json POST 发送一个 cookie:
public function testAccessCookie()
{
$response = $this->json('POST', route('publications'))->withCookie(Cookie::create('test'));
//some asserts
}
Run Code Online (Sandbox Code Playgroud)
发布路线有一些中间件:
public function handle($request, Closure $next)
{
Log::debug('cookie', [$request->cookies]);
//cookie validation
return $next($request);
}
Run Code Online (Sandbox Code Playgroud)
但是在运行时testAccessCookie(),[null]里面有日志。没有附加饼干。
怎么了?
真正的(浏览器内)请求没有这样的问题。
我在 Laravel 5.7 中有以下工厂,在调用它时没有返回任何内容:
<?php
use Faker\Generator as Faker;
use Illuminate\Database\Eloquent\Model;
$factory->define(App\Record::class, function (Faker $faker) {
return [
"name" => $faker->name,
];
});
Run Code Online (Sandbox Code Playgroud)
而我的模型是:
<?php
namespace App;
use App\Product;
use Illuminate\Database\Eloquent\Model;
class Record extends Model
{
protected $table = "records";
protected $fillable = ["name"];
function __construct()
{
parent::__construct();
}
}
Run Code Online (Sandbox Code Playgroud)
我在这里调用工厂:
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App;
use App\Product;
use App\Record;
use App\User;
class RecordTest extends TestCase
{
use RefreshDatabase;
use …Run Code Online (Sandbox Code Playgroud) 我的应用程序中有两个不同的用户对象,一个App\User和一个App\Admin。对于两者,我都有不同的身份验证保护。
我的默认守卫是web模型守卫App\User,我也有admin模型守卫App\Admin。
例如,这段代码
$admin = factory(\App\Admin::class)->make();
\Auth::guard('admin')->login($admin);
dd([\Auth::check(), \Auth::guard('admin')->check()]);
Run Code Online (Sandbox Code Playgroud)
返回
[假,真]
正如预期的那样。
但是,在我的功能测试中,我正在这样做:
$admin = factory(\App\Admin::class)->make();
$response = $this->actingAs($admin, 'admin')
->get('/admin');
dd([\Auth::check(), \Auth::guard('admin')->check()]);
Run Code Online (Sandbox Code Playgroud)
这出于某种原因返回
[真实,真实]
这会导致各种错误(例如,我有一个普通用户的日志中间件,并尝试将管理员存储为普通用户会引发外键异常等)。
为什么同时actingAs启用两个守卫?这是 Laravel 5.6 中的错误还是我做错了什么?
我必须使用下面给出的 setUp 函数进行 PHPUnit 测试:
use PHPUnit\Framework\TestCase;
class UserTest extends TestCase
{
public function setUp()
{
var_dump('1');
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行此测试时,它会显示以下错误:
PHP Fatal error: Declaration of UserTest::setUp() must be compatible with PHPUnit\Framework\TestCase::setUp(): void
Run Code Online (Sandbox Code Playgroud)
我该如何解决?
我是 php 单元测试的新手。如何在下面的函数中模拟日期。目前它正在获取当前日期。但我想将模拟中的日期更改为一个月的第一天。
function changeStartEndDate() {
if (date('j', strtotime("now")) === '1') {
$this->startDate = date("Y-n-j", strtotime("first day of previous month"));
$this->endDate = date("Y-n-j", strtotime("last day of previous month")) . ')';
} else {
$this->startDate = date("Y-n-j", strtotime(date("Y-m-01")));
$this->endDate = date("Y-n-j", strtotime("yesterday"));
}
}
Run Code Online (Sandbox Code Playgroud)
我试过这样做,但它不起作用。
public function testServicesChangeStartEndDate() {
$mock = $this->getMockBuilder('CoreFunctions')
->setMethods(array('changeStartEndDate'))
->getMock();
$mock->method('changeStartEndDate')
->with(date("Y-n-j", strtotime(date("Y-m-01"))));
$this->assertSame(
'1',
$this->core->changeStartEndDate()
);
}
Run Code Online (Sandbox Code Playgroud) 当在模拟对象上调用任何未配置的方法时,是否有可能让 PHPUnit 失败?
例子;
$foo = $this->createMock(Foo::class);
$foo->expects($this->any())->method('hello')->with('world');
$foo->hello('world');
$foo->bye();
Run Code Online (Sandbox Code Playgroud)
这个测试会成功。我希望它失败
Foo::bye() was not expected to be called.
Run Code Online (Sandbox Code Playgroud)
PS 以下可以工作,但这意味着我必须在回调中列出所有配置的方法。这不是一个合适的解决方案。
$foo->expects($this->never())
->method($this->callback(fn($method) => $method !== 'hello'));
Run Code Online (Sandbox Code Playgroud) 无法对特定文件运行测试,导致 PhpStorm 将命名空间添加到最终命令
Testing started at 14:36 ...
[sftp://inf@127.0.0.1:22]:/usr/bin/php /mnt/d/MP/mp.kz/phpunit.phar --bootstrap /mnt/d/MP/mp.kz/vendor/autoload.php --configuration /mnt/d/MP/mp.kz/phpunit.xml MP\\Tests\\Auction\\AuctionsListPublicSearchServiceTest /mnt/d/MP/mp.kz/tests/Auction/AuctionsListPublicSearchServiceTest.php --teamcity --cache-result-file=/mnt/d/MP/mp.kz/.phpunit.result.cache
PHPUnit 9.0.1 by Sebastian Bergmann and contributors.
Cannot open file "MP\\Tests\\Auction\\AuctionsListPublicSearchServiceTest".
Process finished with exit code 1
Run Code Online (Sandbox Code Playgroud)
PhpStorm 将命名空间添加到命令行。
如果我从命令行中删除命名空间,那么它可以正常工作:
[SANDBOX]inf@NM0-MP:~$ /usr/bin/php /mnt/d/MP/mp.kz/phpunit.phar --bootstrap /mnt/d/MP/mp.kz/vendor/autoload.php --no-configuration /mnt/d/MP/mp.kz/tests/Auction/AuctionsListPublicSearchServiceTest.php
PHPUnit 9.0.1 by Sebastian Bergmann and contributors.
. 1 / 1 (100%)
Time: 1.48 seconds, Memory: 18.00 MB
OK (1 test, 3 assertions)
[SANDBOX]inf@NM0-MP:~$
Run Code Online (Sandbox Code Playgroud) phpunit ×10
php ×9
unit-testing ×2
factory ×1
fatal-error ×1
httprequest ×1
laravel ×1
laravel-5 ×1
laravel-5.7 ×1
mocking ×1
namespaces ×1
pear ×1
phpstorm ×1
xampp ×1