我在测试一个简单的 Laravel 项目时遇到问题。Laravel 版本是 5.1,PHPUnit 版本是 5.2.4。例子:
<?php
class MissionTest extends TestCase {
/*
* @test
*/
public function f1() {
return [];
}
/*
* @test
* @depends f1
*/
public function f2($a) {
dd($a);
}
public function testF1() {
return [];
}
/*
* @depends testF1
*/
public function testF2($a) {
dd($a);
}
}
?>
Run Code Online (Sandbox Code Playgroud)
预期的行为是执行 f1 print one fullstop,然后执行 f2 并输出一个空数组。实际发生的情况是测试 f1 和 f2 被忽略,执行 testF1 导致一个句号,然后执行 testF2 导致一个 E。例外是:
ErrorException:MissionTest::testF2() 缺少参数 1
我刚刚开始使用 PHPUnit,无论我尝试什么,我都无法让它按预期工作。任何帮助将不胜感激。
编辑:忘记提及 TestCase …
我在我的 phpunit 测试类中扩展 Symfony\Bundle\FrameworkBundle\Test\KernelTestCase
我想让entityManager 获取数据库中的一些数据。
我怎样才能做到这一点?
看起来我必须初始化parent::kernel,但我不知道应该将哪4个参数传递给构造函数。
谢谢
我有一个执行 mysql 操作的示例类,如下所示。
<?php
class ProjectHandler{
public function getProjectInformation($projectId){
$prMysql = new prMysql;
/* Make connection to database */
$connection = $prMysql->open_store_database();
$sql = sprintf("SELECT product_id, projectName FROM test_projects
WHERE projectId = %d", $platform_id);
$test_result = mysql_query($sql, $connection) or die();
$num_rows = mysql_num_rows($test_result);
if ($num_rows > 0) {
$test_row = mysql_fetch_assoc($test_result);
}
return $test_row;
}
}
?>
Run Code Online (Sandbox Code Playgroud)
哪里prMysql有一个为mysql操作编写的包装类。是否可以模拟场景中的 mysql 调用?
正如标题所述,我期待找到一种方法来防止error_log()在测试期间在终端中打印消息PHPUnit。
在上面的示例中,被测试的方法通过 error_log('Don\'t show up'),在测试之间打印其消息。
有什么方法可以防止这种行为,让我的测试日志保持美观?另外,有什么方法可以捕获消息并测试其输出吗?(对于消息不是简单字符串的情况)。
我在Laravel 文档中看到可以设置这样的测试期望:
Cache::shouldReceive('get')
->once()
->with('key')
->andReturn('value');
Run Code Online (Sandbox Code Playgroud)
然后我在PHPunit 文档中看到灵活的参数匹配是可能的,如下所示:$this->stringContains('Something')。
但是当我编辑我的测试时:
Log::shouldReceive('error')
->once();
->with($this->stringContains('Contact does not exist'));
Run Code Online (Sandbox Code Playgroud)
...然后我收到以下错误:
Mockery\Exception\NoMatchingExpectationException: No matching handler found for Mockery_1_Illuminate_Log_Writer::error("Contact does not exist blah blah etc").
Either the method was unexpected or its arguments matched no expected argument list for this method
Run Code Online (Sandbox Code Playgroud)
我怎样才能实现我的目标(通过灵活的参数匹配Log::shouldReceive)?
PS我也尝试过->with(\PHPUnit\Framework\Assert::stringContains('Contact does not exist'))。
我想使用 phpunit 桥在 Symfony 4 中测试我的服务,但是当我启动测试时,我得到:
Error: Class 'App\Service\CompanyManager' not found
Run Code Online (Sandbox Code Playgroud)
我的服务位于 src/Service/CompanyManager.php
测试/Service/CompanyManagerTest.php:
namespace App\Tests\Service;
use App\Service\CompanyManager;
use PHPUnit\Framework\TestCase;
use App\Entity\Company;
class CompanyManagerTest extends TestCase
{
public function testGetCompany()
{
$companyManager = new CompanyManager();
$company = $companyManager->getCompany(2);
$this->assertInstanceOf(Company::class,$company);
$company = $companyManager->getCompany(1000);
$this->assertNull($company);
}
}
Run Code Online (Sandbox Code Playgroud)
在config/services_test.yaml中,有这样的语句:
# If you need to access services in a test, create an alias
# and then fetch that alias from the container. As a convention,
# aliases are prefixed with test. For example: …Run Code Online (Sandbox Code Playgroud) 我有一个服务类:
class OutletTableWriter
{
private $validator;
private $entityManager;
public function __construct(ValidatorInterface $validator, EntityManagerInterface $em)
{
$this->validator = $validator;
$this->em = $em;
}
// inserts outlet to db
public function insertOutlet($outletName, $buildingName = null, $propertyNumber, $streetName, $area, $town, $contactNumber, $postcode)
{
$outlet = new Outlet();
$outlet->setOutletName($outletName);
$outlet->setBuildingName($buildingName);
$outlet->setPropertyNumber($propertyNumber);
$outlet->setStreetName($streetName);
$outlet->setArea($area);
$outlet->setTown($town);
$outlet->setContactNumber($contactNumber);
$outlet->setPostCode($postcode);
$outlet->setIsActive(0);
// $validator = $this->get('validator'); // validate constraints
$errors = $this->validator->validate($outlet);
if (count($errors) > 0) {
$response = new Response('', 422, array('content-type' => 'text/html'));
$errorsString = (string) $errors; …Run Code Online (Sandbox Code Playgroud) 我在 Laravel 5.6 应用程序中使用了一个特征。该特征称为Projectable. 此特征旨在由 Eloquent 模型使用。为了测试该特征,我想创建一个ProjectableStub用于测试的模型。然而,由于这是一个 Eloquent 模型,因此它需要一个表。
我想简单地创建并删除一个表以进行测试。然而,当我这样做时,功能似乎出现了一些问题RefreshDatabase。为了演示,我只是运行两个测试,这两个Product测试都尝试使用id = 1. 由于RefreshDatabase正在使用该特征,因此这应该可以正常工作。并且,在下面的示例中,它确实:
<?php
namespace Tests\Feature;
use App\Product;
use Tests\TestCase;
use App\Concerns\Projectable;
use Illuminate\Support\Facades\Schema;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Database\Eloquent\Model as Eloquent;
class ProjectableTest extends TestCase
{
use RefreshDatabase;
public function setUp()
{
parent::setUp();
//$this->createStubTable();
}
/**
* @test
*/
public function example_first_test()
{
factory(Product::class)->create(['id' => 1]);
}
/**
* @test
*/
public function example_second_test()
{
factory(Product::class)->create(['id' => …Run Code Online (Sandbox Code Playgroud) 我正忙于学习 Laravel 的单元测试,我有一个问题。我希望在运行其他所有其他测试之前先运行一个与身份验证有关的测试。这能实现吗?
到目前为止,我有 4 个测试类,其中有一些方法。
我使用 Symfony 的 KernelTestCase 编写单元测试,并且必须测试功能,该功能仅在当天的某个时间(特别早或特别晚)发生。
因此,当我让测试运行一个中午时,当然什么也没有发生。我如何伪造我的系统时间来假装它有不同的时间并且我的测试用例被触发。
我尝试使用 Symfony 的 ClockMock 类,但它不起作用。 https://symfony.com/doc/current/components/phpunit_bridge.html#clock-mocking
这是我的测试代码:
use Symfony\Bridge\PhpUnit\ClockMock;
use \DateTime;
/**
* testUserAchievedEarlyBirdTrophy
* @group time-sensitive
*/
public function testUserAchievedEarlyBirdTrophy()
{
ClockMock::withClockMock(strtotime('2018-11-05 01:00:00'));
echo (new DateTime())->format('Y-m-d H:m:s');
$user8Id = $this->user8->getId();
$progressSaveRequest = new ProgressSaveRequest($user8Id, $this->content_1_1->getId());
$this->progressService->saveProgress($progressSaveRequest);
$this->assertTrue($this->loggerCreator->hasDebugThatContains(
'Early Bird'
));
}
Run Code Online (Sandbox Code Playgroud)
回声给我今天的日期:2019-02-01 16:02:06
我也有一种感觉,ClockMock 更适合用来跳过时间,例如测试缓存而不是 sleep()。
我究竟做错了什么?
侦听器配置位于我的 phpunit.xml 中,调用 bin/simple-phpunit 会导致发生大量安装。
我不能使用普通的 phpunit 吗?
还有其他选项可以伪造一天中的时间吗?