我正在尝试在我的控制器中设置最简单的测试,但是,与大多数事物Laravel一样,没有像样的教程来演示这些简单的东西。
我可以运行一个简单的测试(在一个名为UserControllerTest的文件中),如下所示:
public function testIndex()
{
$this->call('GET', 'users');
$this->assertViewHas('users');
}这将调用/users路由并传入数组users。
我也想对Mockery做同样的事情,但是怎么做呢?
如果我尝试这样做:
public function testIndex()
{
$this->mock->shouldReceive('users')->once();
$this->call('GET', 'users');
}我得到一个错误:“静态方法Mockery__users::all在这个模拟对象上不存在。
为什么不行?我在嘲笑用户,它扩展了Ardent,而反过来又扩展了Eloquent。为什么::都不是为mock而存在的?
顺便说一句,以下是Mockery的设置函数:
public function setUp()
{
parent::setUp();
$this->mock = $this->mock('User');
}
public function mock($class)
{
$mock = Mockery::mock($class);
$this->app->instance($class, $mock);
return $mock;
}发布于 2014-09-08 22:29:20
您不能直接模拟一个雄辩的类。Eloquent不是门面,你的用户模型也不是。Laravel有一点魔力,但你不能做那样的事情。
如果你想模拟你的User类,你必须把它注入到控制器构造函数中。如果您想这样做,那么存储库模式是一种很好的方法。在Google上有很多关于这个模式和Laravel的文章。
下面是一些代码片段,向您展示它是什么样子的:
class UserController extends BaseController {
public function __construct(UserRepositoryInterface $users)
{
$this->users = $users;
}
public function index()
{
$users = $this->users->all();
return View::make('user.index', compact('users'));
}
}
class UserControllerTest extends TestCase
{
public function testIndex()
{
$repository = m::mock('UserRepositoryInterface');
$repository->shouldReceive('all')->andReturn(new Collection(array(new User, new User)));
App::instance('UserRepositoryInterface', $repository);
$this->call('GET', 'users');
}
}如果你的项目看起来太结构化了,你可以在测试中调用一个真正的数据库,而不是模仿你的模型类……在一个经典的项目中,它工作得很好。
发布于 2017-03-28 23:03:02
这个function是一个名为apiato.io的项目的一部分,你可以用它来模拟Laravel中的任何类,甚至facade,基本上任何可以用IoC解决的类,如果你使用正确的依赖注入,它几乎是所有的类:
/**
* Mocking helper
*
* @param $class
*
* @return \Mockery\MockInterface
*/
public function mock($class)
{
$mock = Mockery::mock($class);
App::instance($class, $mock);
return $mock;
}https://stackoverflow.com/questions/25724391
复制相似问题