ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
### **Build A Contract** First, we'll define an interface and a corresponding implementation: ~~~ interface UserRepositoryInterface { public function all(); } class DbUserRepository implements UserRepositoryInterface { public function all() { return User::all()->toArray(); } } ~~~ Now our controller is completely ignorant of where our user data is being stored. In this case, ignorance is bless! Our data could be coming from MySQL, MongoDB, or Redis. Our controller doesn't know the difference, nor should it care. Just by making this small change, we can test our web layer independent of our data layer, as well as easily switch our storage implementation. > **Respect Boundaries** > > Remember to respect responsibility boundaries. Controllers and routes serve as a mediator between HTTP and your application. When writing large applications, don't clutter them up with your domain logic. > To solidify our understanding, let's write a quick test. First, we'll mock the repository and bind it to the application IoC container. Then, we'll ensure that the controller properly calls the repository: ~~~ public function testIndexActionBindsUsersFromRepository() { // Arrange... $repository = Mockery::mock('UserRepositoryInterface'); $repository->shouldReceive('all')->once()->andReturn(array('foo')); App::instance('UserRepositoryInterface', $repository); // Act... $response = $this->action('GET', 'UserController@getIndex'); // Assert... $this->assertResponseOk(); $this->assertViewHas('users', array('foo')); } ~~~ > **Are you Mocking Me** > > In this example, we used the `Mockery` mocking library. This library provides a clean, expressive interface for mocking your classes. Mockery can be easily insalled via Composer. >