2015-01-02 3 views
4

나는 간단한 클래스를 테스트하려고합니다. 이 자습서 (http://code.tutsplus.com/tutorials/testing-laravel-controllers--net-31456)를 따르고 있습니다. 테스트를 실행하는 동안메서드가이 모의 객체에 존재하지 않습니다. - Laravel, Mockery

나는이 오류가 :

Method Mockery_0_App_Interfaces_MealTypeRepositoryInterface::getValidator() does not exist on this mock object 

임 저장소 구조를 사용하여. 그래서, 내 컨트롤러 저장소를 호출하고 Eloquent의 응답을 반환합니다.

저는 PHP와 laravel에서 비교적 새롭습니다. 며칠 전에 테스트를 시작 했으므로 지저분한 코드에 대해 유감입니다.

내 테스트 케이스 :

class MealTypeControllerTest extends TestCase 
{ 
public function setUp() 
{ 
    parent::setUp(); 

    $this->mock = Mockery::mock('App\Interfaces\MealTypeRepositoryInterface'); 
    $this->app->instance('App\Interfaces\MealTypeRepositoryInterface' , $this->mock); 
} 
public function tearDown() 
{ 
    Mockery::close(); 
} 

public function testIndex() 
{ 
    $this->mock 
     ->shouldReceive('all') 
     ->once() 
     ->andReturn(['mealTypes' => (object)['id' => 1 , 'name' => 'jidlo']]); 

    $this->call('GET' , 'mealType'); 

    $this->assertViewHas('mealTypes'); 
} 

public function testStoreFails() 
{ 
    $input = ['name' => 'x']; 

    $this->mock 
     ->shouldReceive('getValidator') 
     ->once() 
     ->andReturn(Mockery::mock(['fails' => true])); 

    $this->mock 
     ->shouldReceive('create') 
     ->once() 
     ->with($input); 


    $this->call('POST' , 'mealType' , $input); // this line throws the error 

    $this->assertRedirectedToRoute('mealType.create');//->withErrors(); 

    $this->assertSessionHasErrors('name'); 
} 

} 

내 EloquentMealTypeRepository : 정말 흥미 아무것도.

class EloquentMealTypeRepository implements MealTypeRepositoryInterface 
{ 
public function all() 
{ 
    return MealType::all(); 
} 

public function find($id) 
{ 
    return MealType::find($id); 
} 

public function create($input) 
{ 
    return MealType::create($input); 
} 

public function getValidator($input) 
{ 
    return MealType::getValidator($input); 
} 
} 

내 웅변 구현 : 정말 너무 인터 휴식 아무 것도.

class MealType extends Model 
{ 
private $validator; 

/** 
* The database table used by the model. 
* 
* @var string 
*/ 
protected $table = 'meal_types'; 

/** 
* The attributes that are mass assignable. 
* 
* @var array 
*/ 
protected $fillable = ['name']; 

/** 
* The attributes excluded from the model's JSON form. 
* 
* @var array 
*/ 
protected $hidden = []; 

public function meals() 
{ 
    return $this->hasMany('Meal'); 
} 

public static function getValidator($fields) 
{ 
    return Validator::make($fields, ['name' => 'required|min:3']); 
} 
} 

내 MealTypeRepositoryInterface :

interface MealTypeRepositoryInterface 
{ 
public function all(); 

public function find($id); 

public function create($input); 

public function getValidator($input); 
} 

그리고 마지막으로, 내 컨트롤러 :

class MealTypeController extends Controller { 
protected $mealType; 

public function __construct(MealType $mealType) 
{ 
    $this->mealType = $mealType; 
} 


/** 
* Display a listing of the resource. 
* 
* @return Response 
*/ 
public function index() 
{ 
    $mealTypes = $this->mealType->all(); 
    return View::make('mealTypes.index')->with('mealTypes' ,$mealTypes); 
} 

/** 
* Show the form for creating a new resource. 
* 
* @return Response 
*/ 
public function create() 
{ 
    $mealType = new MealTypeEloquent; 
    $action = '[email protected]'; 
    $method = 'POST'; 

    return View::make('mealTypes.create_edit', compact('mealType' , 'action' , 'method'));  
} 

/** 
* Validator does not work properly in tests. 
* Store a newly created resource in storage. 
* 
* @return Response 
*/ 
public function store(Request $request) 
{ 
    $input = ['name' => $request->input('name')]; 

    $mealType = new $this->mealType; 

    $v = $mealType->getValidator($input); 

    if($v->passes()) 
    { 
     $this->mealType->create($input); 
     return Redirect::to('mealType'); 
    } 
    else 
    { 
     $this->errors = $v; 
     return Redirect::to('mealType/create')->withErrors($v); 
    } 
} 

/** 
* Display the specified resource. 
* 
* @param int $id 
* @return Response 
*/ 
public function show($id) 
{ 
    return View::make('mealTypes.show' , ['mealType' => $this->mealType->find($id)]); 
} 

/** 
* Show the form for editing the specified resource. 
* 
* @param int $id 
* @return Response 
*/ 
public function edit($id) 
{ 
    $mealType = $this->mealType->find($id); 
    $action = '[email protected]'; 
    $method = 'PATCH'; 
    return View::make('mealTypes.create_edit')->with(compact('mealType' , 'action' , 'method')); 
} 

/** 
* Update the specified resource in storage. 
* 
* @param int $id 
* @return Response 
*/ 
public function update($id) 
{ 
    $mealType = $this->mealType->find($id); 
    $mealType->name = \Input::get('name'); 
    $mealType->save(); 
    return redirect('mealType'); 
} 

/** 
* Remove the specified resource from storage. 
* 
* @param int $id 
* @return Response 
*/ 
public function destroy($id) 
{ 
    $this->mealType->find($id)->delete(); 
    return redirect('mealType'); 
} 

} 

모든 것을해야합니다. 응용 프로그램이 작동하고 테스트가 엉망이라고 말하는 것은 가치가 있습니다. 아무도 몰라, 왜 그런 일이 일어나는거야? TestCase의 메소드들 - testIndex와 testStoreFails의 차이점을 알지 못합니다. 왜 "all"메소드가 발견되었고 "getValidator"는 그렇지 않은지. 조언에 대한 조언을 전할 때 감사 할 것입니다.

답변

1

컨트롤러에서이 버그의 원인을 발견했습니다. 호출 아마도 대신 바로

$v = $this->mealType->getValidator($input);

5

의 잘못된

$v = $mealType->getValidator($input);

여담이지만 직접 관련 제목으로이 질문에 찾는 사람에게 :

경우 :

  1. 오류 BadMethodCallException: Method Mockery_0_MyClass::myMethod() does not exist on this mock object을 받고, 그리고 모의 객체의
  2. 것도 피사체의 방법 중 하나를 따기되지 않으며,
  3. 수업이 자동으로 적재되고, (예를 들어,사용 작곡가)

는 다음 모의 객체를하기 전에, 당신은이 코드 줄을 사용하여, 그 주제의 로딩을 강제해야

spl_autoload_call('MyNamespace\MyClass'); 

그럼 당신은 그것을 조롱 수 있습니다

$mock = \Mockery::mock('MyNamespace\MyClass'); 

필자는 PHPUnit 테스트에서 첫 번째 라인을 setUpBeforeClass() 정적 함수에 넣기 때문에 테스트는 한 번 호출되고 추가/삭제되는 테스트와 격리됩니다. 그래서 테스트 클래스는 다음과 같습니다

class MyClassTest extends PHPUnit_Framework_TestCase { 
    public static function setUpBeforeClass() { 
     parent::setUpBeforeClass(); 
     spl_autoload_call('Jodes\MyClass'); 
    } 
    public function testIt(){ 
     $mock = \Mockery::mock('Jodes\MyClass'); 
    } 
} 

내가 세 번 이제 이것에 대해마다 지구에 문제가 무엇인지 궁금 두 시간을 소비를 잊어 버린!

관련 문제