2016-04-24 69 views
0

一直在寻找所有在互联网上,但似乎还没有找到解决我的问题。我一直在使用PHPUnit和Mockery进入Laravel测试控制器。但是,我似乎并没有让我基于雄辩的模型正确地被嘲笑。我确实设法以相同的方式嘲弄我的Auth :: user(),虽然这在下面的测试中没有使用。在AddressControllerLaravel 5 - 用嘲弄嘲弄雄辩模型

功能需要被测试:

public function edit($id) 
{ 
    $user = Auth::user(); 
    $company = Company::where('kvk', $user->kvk)->first(); 
    $address = Address::whereId($id)->first(); 

    if(is_null($address)) { 
     return abort(404); 
    } 

    return view('pages.address.update') 
     ->with(compact('address')); 
} 

含有延伸ControllerTest

class AddressControllerTest extends ControllerTest 
{ 
    /** 
    * @var \App\Models\Address 
    */ 
    private $_address; 

    /** 
    * @var \App\Http\Controllers\AddressController 
    */ 
    protected $_controller; 

    public function setUp(){ 
     parent::setUp(); 
     $this->_controller = new AddressController(); 
     $this->_address = factory(Address::class)->make(); 
    } 

    public function testEdit404(){ 
     $companyMock = $this->mock(Company::class); 
     $companyMock 
      ->shouldReceive('where') 
      ->with('kvk', Mockery::any()) 
      ->once(); 
      ->andReturn(factory(Company::class)->make([ 
       'address_id' => $this->_address->id 
      ])); 

     $addressMock = $this->mock(Address::class); 
     $addressMock 
      ->shouldReceive('whereId') 
      ->with($this->_address->id) 
      ->once(); 
      ->andReturn(null); 

     //First try to go to route with non existing address 
     $this->action('GET', '[email protected]edit', ['id' => $this->_address->id]); 
     $this->assertResponseStatus(404); 
    } 
} 

它保持投掷是该错误安装程序和模拟方法

abstract class ControllerTest extends TestCase 
{ 
    /** 
    * @var \App\Http\Controllers\Controller 
    */ 
    protected $_controller; 

    public function setUp(){ 
     parent::setUp(); 
     $this->createApplication(); 
    } 

    public function tearDown() 
    { 
     parent::tearDown(); 
     Mockery::close(); 
    } 

    protected function mock($class) 
    { 
     $mock = Mockery::mock($class); 
     $this->app->instance($class, $mock); 
     return $mock; 
    } 
} 

AddressControllerTest ControllerTest:

1) AddressControllerTest::testEdit404 
Mockery\Exception\InvalidCountException: Method where("kvk", object(Mockery\Matcher\Any)) from Mockery_1_Genta_Models_Company should be called exactly 1 times but called 0 times. 

也许任何人有一个想法?

+0

,同时检查,如果我的控制器的方法得到了所有调用,它置换后的确与$这个 - >行动()方法取代了$这个 - >()方法调用。但问题依然存在。 –

回答

5

好吧,由Jeffrey路(后面Laracasts的家伙)发现多个帖子,建议人们停止嘲笑雄辩对象和内存数据库,而不是使用我试过这种方法之后。我认为这对未来有相同问题的其他用户可能非常有用,所以我会在下面解释。

现在我已经编辑了我的“的config/database.php中”文件,以支持内存数据库选项使用SQLite:

'sqlite' => [ 
      'driver' => 'sqlite', 
      'database' => ':memory:', 
      'prefix' => '', 
     ], 

接下来你会看到下面的配置文件的顶部:

'default' => env('DB_CONNECTION', 'mysql'), 

这可以保持不变,这意味着Laravel将检查您的.ENV变量来找到一个“DB_CONNECTION”或者使用MySQL作为默认。这可能是您像平常一样运行应用程序时要执行的操作。但是,通过测试,您希望覆盖此配置,并将数据库配置临时设置为'sqlite'。这可以通过添加“DB_CONNECTION”变量设置为.ENV文件来完成:

DB_CONNECTION=mysql 

最后,在你的phpunit.xml,使用Laravel到instantiatie单元测试配置文件,你一定要告诉,当测试这个变量应设置为“源码”:

<env name="DB_CONNECTION" value="sqlite"/> 

现在你完成和Laravel将启动一个无形的内存数据库每次你即将去测试。不要忘记将以下行添加到需要数据库的测试中。

use \Illuminate\Foundation\Testing\DatabaseMigrations; 

它会告诉Laravel在开始测试之前运行数据库迁移,因此您可以像平常一样使用表格。

这样,它完全适用于我!希望你们可以使用它。

+0

适合我。谢谢。迁移后我也播种了数据库。只是一个警告:你会发现'@depends testCreateCard' notation可以让我们说一个从方法到方法的ID,因为'setUp()'每次测试运行一次,每次DB都会被重置。我解决了播种我的数据并使用硬编码值。 – mayid