【问题标题】:Laravel Testing ErrorLaravel 测试错误
【发布时间】:2014-08-11 06:58:34
【问题描述】:

我刚开始学习如何在 Laravel 中进行测试。虽然我遇到了一些问题.. 我正在测试我的控制器并想检查视图是否分配了变量。

我的控制器代码:

class PagesController extends \BaseController {

   protected $post;

   public function __construct(Post $post) {
      $this->post = $post;
   }

   public function index() {
      $posts = $this->post->all();
      return View::make('hello', ['posts' => $posts]);
   }
}

我的视图包含一个 foreach 循环来显示所有帖子:

@foreach ($posts as $post)
   {{post->id}}
@endforeach

最后但并非最不重要的是我的测试文件:

class PostControllerTest extends TestCase {

public function __construct()
{
    // We have no interest in testing Eloquent
    $this->mock = Mockery::mock('Eloquent', 'Post');
}

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

public function testIndex() {

    $this->mock->shouldReceive('all')->once()->andReturn('foo');
    $this->app->instance('Post', $this->mock);
    $this->call('GET', '/');
    $this->assertViewHas('posts');

}

}

现在问题来了,当我运行“phpunit”时出现以下错误:

ErrorException:为 foreach() 提供的参数无效

任何想法为什么 phpunit 返回此错误?

【问题讨论】:

    标签: testing laravel controller tdd


    【解决方案1】:

    你的问题在这里:

    $this->mock->shouldReceive('all')->once()->andReturn('foo');
    

    $this->post->all()(这是你在嘲笑的)应该返回一个数组,这就是你的视图所期望的。你正在返回一个字符串。

    $this->mock->shouldReceive('all')->once()->andReturn(array('foo'));
    

    应该注意您遇到的错误,尽管您会收到“获取非对象属性”类型的错误。

    你可以这样做:

    $mockPost = new stdClass();
    $mockPost->id = 1;
    $this->mock->shouldReceive('all')->once()->andReturn(array($mockpost));
    

    【讨论】:

    • 谢谢!这有效,但只有当我添加 {{posts}} 时它才会给出错误:数组到字符串转换。有没有办法解决这个问题?
    • 我使用 FactoryMuff 创建一个快速帖子,如下所示: $mockPost = FactoryMuff::create('Post');然而,当我调用 {{$posts}} 时,这并没有解决问题,但它确实填充了 Post 的所有其他字段(例如正文)。
    • 您不能只回显 {{posts}} 因为它是一个数组——您需要循环它并回显各个条目,就像您问题中的代码一样。
    • 啊,对不起.. 当您执行 {{$posts}} 时,laravel 会将数组转换为 json,而这在我的测试中没有完成。无论如何,谢谢,我的错在那里;)
    【解决方案2】:

    你也应该模拟视图:

    public function testIndex() {
        $this->mock->shouldReceive('all')->once()->andReturn('foo');
        $this->app->instance('Post', $this->mock);
        View::shouldReceive('make')->with('hello', array('posts', 'foo'))->once();
        $this->call('GET', '/');
    }
    

    【讨论】:

    • 这对我不起作用。它返回以下错误:ErrorException: Trying to get property of non-object
    • 我修好了。忽略原来的答案,就这样做
    • 您是否将模型的模拟切换回代码中的原始模型?即它应该回到$this->mock->shouldReceive('all')->once()->andReturn('foo'); - 不再是数组......?
    • 这也不起作用。错误:Mockery\Exception\NoMatchingExpectationException:没有为 Mockery_1_Illuminate_View_Factory::make("hello", array('posts'=>'foo',)) 找到匹配的处理程序。该方法是意外的,或者它的参数与该方法的预期参数列表不匹配
    • 是的,我完全按照您在更新答案中所说的做了。如果我用我的代码替换 @foreach 等 {{posts}},则测试成功。它必须与 foreach 或其他东西有关。
    猜你喜欢
    • 2016-06-04
    • 1970-01-01
    • 2016-05-21
    • 2013-12-28
    • 2017-03-07
    • 2018-08-05
    • 2021-04-08
    • 2016-01-26
    • 1970-01-01
    相关资源
    最近更新 更多