我目前正在尝试遵循存储库模式,而且我已经到了需要测试存储库的部分。我试图测试的是调用create函数并模拟结果而不实际访问数据库。但是在运行测试时,我最终得到了错误:
PDOException: SQLSTATE[HY000] [2003] Can't connect to MySQL server on 'mysql' (113)
这是我的测试文件的样子:
<?php
class UserRepositoryTest extends TestCase
{
private $user;
public function __construct()
{
$this->mock = Mockery::mock('App\User');
$this->user = new \App\Repositories\UserRepository(new Illuminate\Container\Container, new \Illuminate\Support\Collection);
}
public function setUp()
{
parent::setUp();
}
public function tearDown()
{
Mockery::close();
}
public function testCreate()
{
$this->mock
->shouldReceive('create')
->withAnyArgs()
->once()
->andReturn(array());
$user = $this->user->create(['password' => 'secret']);
}
}
这是用户存储库的样子:
<?php
namespace App\Repositories;
use App\Repositories\Eloquent\Repository;
use Illuminate\Support\Facades\Hash;
class UserRepository extends Repository
{
/**
* Specify Model class name.
*
* @return mixed
*/
public function model()
{
return 'App\User';
}
/**
* @param array $data
*
* @return mixed
*/
public function create(array $data)
{
$data['partner_status'] = 'Active';
$data['password'] = Hash::make($data['password']);
return parent::create($data);
}
}
父母的创建功能如下所示:
/**
* @param array $data
*
* @return mixed
*/
public function create(array $data)
{
return $this->model->create($data);
}
我如何模拟它以便实际返回我告诉它返回的内容?
答案 0 :(得分:2)
模拟对象会创建一个特定的模拟实例。它不会影响任何其他创建该类型对象的新实例的代码。例如:
$mock = Mockery::mock('App\User');
$user = new \App\User();
在上面的示例中,$mock
将是您的模拟对象的实例,但$user
仍然是普通的User
对象,根本与模拟无关。
这项测试实际上引领您走向更好的设计之路。目前,您的UserRepository
对\App\User
类隐藏了依赖关系。要解决此问题,您应该将依赖项添加到存储库的构造函数中,以便在创建存储库时注入该依赖项。
通过将依赖项添加到构造函数中,它不再被隐藏,并且您将能够注入您的模拟对象,而不是让存储库尝试创建更难以测试的新对象,因为您已经发现了。
因此,您的存储库看起来像:
class UserRepository extends Repository
{
public function __construct(\App\User $model, \Illuminate\Container\Container $container, \Illuminate\Support\Collection $collection) {
$this->model = $model;
$this->container = $container;
$this->collection = $collection;
}
}
然后你的测试看起来像:
class UserRepositoryTest extends TestCase
{
public function __construct()
{
$this->mock = Mockery::mock('App\User');
}
public function testCreate()
{
$this->mock
->shouldReceive('create')
->withAnyArgs()
->once()
->andReturn(array());
$repo = new \App\Repositories\UserRepository($this->mock, new Illuminate\Container\Container, new \Illuminate\Support\Collection);
$user = $repo->create(['password' => 'secret']);
}
}
答案 1 :(得分:0)
您是否在config/database.php
?
举例来说:
'testing' => [
'driver' => 'mysql',
'host' => env('DB_TEST_HOST', 'localhost'),
'port' => env('DB_TEST_PORT', '3306'),
'database' => env('DB_TEST_DATABASE', 'homestead_test'),
'username' => env('DB_TEST_USERNAME', 'homestead'),
'password' => env('DB_TEST_PASSWORD', 'secret'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
然后添加一个名为homestead_test
的新数据库,添加名为homestead
的用户并将传递设置为secret
。