title: testing php laravel controller shouldReceive arguments
body: <p>I have a laravel model which uses ardent/eloquent. I am trying to set up tests for the controller in particular, storing a new model that uses the ardent model.</p>
  
  <p>The method works in the app but I'm having trouble with my tests</p>
  
  <p>I'm having problems working out how to mock the calls this method makes.</p>
  
  <p>My controllers set up and the method in question is this one:</p>
  
  <pre><code>use golfmanager\service\creator\TicketCreatorInterface;
  
  //controller manages the ticket books
  
  class BooksController extends BaseController {
  
  /**
   * Book Repository
   *
   * @var Book
   */
  protected $book;
  protected $ticket;
  
  public function __construct(Book $book, TicketCreatorInterface $ticket)
  {
      $this-&gt;book = $book;
      $this-&gt;ticket = $ticket;
  }
  
  public function store()
  
  {
      $input = Input::all();
  
      $result = $this-&gt;book-&gt;save();
  
      if ($result) {
          //if book created then create tickets
  
          $this-&gt;ticket-&gt;createTicket($input, $this-&gt;book);
  
          return Redirect::route('books.index');
      }
  
      return Redirect::route('books.create')
          -&gt;withInput()
          -&gt;withArdentErrors()
          -&gt;with('message', 'There were validation errors.');
  }
  </code></pre>
  
  <p>And the methods used by the interface (TicketCreator):</p>
  
  <pre><code>public function createTicket($input, $book) {
  
      //dd($input);
  
      $counter = $input['start_number'];
  
      while($counter &lt;= $input['end_number']) {
  
          $ticketDetails = array(
              'ticketnumber'=&gt;$counter,
              'status'=&gt;'unused',
              'active'=&gt;1
              );
  
          $this-&gt;ticket-&gt;create($ticketDetails)-&gt;save();
  
          $this-&gt;ticket-&gt;book()-&gt;associate($book)-&gt;save();
  
          $counter = $counter+1;
  
      }
      return $counter;
  }
  </code></pre>
  
  <p><strong>My test</strong> is as follows:</p>
  
  <pre><code>use Mockery as m;
  use Way\Tests\Factory;
  
  class BooksTest extends TestCase {
  
  public function __construct()
  {
      $this-&gt;mock = m::mock('Ardent', 'Book');
      $this-&gt;collection = m::mock('Illuminate\Database\Eloquent\Collection')-&gt;shouldDeferMissing();
  }
  
  public function setUp()
  {
      parent::setUp();
  
      $this-&gt;attributes = Factory::book(['id' =&gt; 1, 'assigned_date'=&gt; '20/11/2013']);
      $this-&gt;app-&gt;instance('Book', $this-&gt;mock);
  }
  
  public function testStore()
  {
      Input::replace($input = ['start_number'=&gt;1000, 'end_number'=&gt;1010, 'assigned_date'=&gt;'20/11/2013']);
  
      $this-&gt;mock-&gt;shouldReceive('save')-&gt;once()-&gt;andReturn(true);
      $this-&gt;ticket-&gt;shouldReceive('createTicket')-&gt;once()-&gt;with($input, $this-&gt;mock)-&gt;andReturn(true);
  
      //with($input);
      //$this-&gt;validate(true);
      $this-&gt;call('POST', 'books');
  
      $this-&gt;assertRedirectedToRoute('books.index');
  }
  </code></pre>
  
  <p>Currently I get an error:</p>
  
  <pre><code>No matching handler found for Book::save()
  </code></pre>
  
  <p>Is this being thrown because the book model doesnt contain a save method? If it is how do I mock the model correctly. I don't want it to touch the database (although it could if it has to).
  Is it the multiple saves in the createTicket method?</p>
  
  <p>Still learning how to set up tests correctly - slowly getting there but not enough knowledge yet.</p>
  
  <p>If I change the name of the method in shouldReceive to say 'store' it still comes up with the save() error message.</p>
  
  <p><strong>Update:</strong>
  I have isolated part of the problem to the createTicket call. I've changed my testStore test and updated as above.</p>
  
  <p>My error with this current test is: <code>Undefined index: start_number</code>. </p>
  
  <p>If I remove the call to createTicket in the controller method I don't get an error. I tried using Input::replace to replace the input from a form but appears not getting through to my function</p>
  
  <p>How can I simulate a form input in the mocked objects?</p>
  
  <p>Thanks</p>