1

我正在使用 Mocha,并试图在功能测试中使用它。

这是我的代码:

  test "should post create" do
    user = FactoryGirl.create(:user)
    UserSession.create(user)
    recipe_attributes = FactoryGirl.attributes_for(:recipe)
    Recipes::Recipe.any_instance.expects(:save)
    post(:create, {'recipes_recipe' => recipe_attributes})
    assert_response(302)
    assert_not_nil(assigns(:recipe))
  end

代码未能assert_response(302)说明响应为200. 当我删除该行时:

    Recipes::Recipe.any_instance.expects(:save)

测试通过。

这是create动作:

def create
  @recipe = Recipe.new(params[:recipes_recipe])

  photo_keys = params.keys.select{|k|k.match(/^photo/)}
  @photos = []
  photo_keys.each do |photo_key|
    @photos << Photo.new(params[photo_key])
  end

  @recipe.tags = Tag.parse(params[:tags])

  @recipe.author = current_user

  photos_valid = !@photos.empty? ? @photos.all?{|photo|photo.save} : true

  puts photos_valid.inspect

  if @recipe.save && photos_valid
    unless @photos.empty?
      @photos.each do |photo|
        photo.recipe_id = @recipe.id
        photo.save
      end
    end
    flash[:notice] = 'Recipe was successfully created.'
    redirect_to recipe_url(@recipe.slug)
  else
    puts @recipe.save.inspect
    puts @recipe.errors.inspect
    flash[:error] = 'Could not create recipe. '
    flash[:error] += 'Please correct any mistakes below.'
    render 'new'
  end
end

当我puts Recipes::Recipe.all.inspectelse子句中放入 a 时,列表是空的,我想这应该是它应该如何工作的,因为 Mocha 的重点是不接触数据库以使测试更快。

所以,我的问题是,在这种情况下我应该如何进行测试?这条线是否足以确保该create操作按应有的方式进行?

Recipes::Recipe.any_instance.expects(:save)
4

1 回答 1

0

这是我想出的解决方案:

  test "should post create" do
    user = FactoryGirl.create(:user)
    UserSession.create(user)

    recipe_attributes = FactoryGirl.attributes_for(:recipe)

    Recipes::Recipe.any_instance.expects(:save).returns(true)
    Recipes::RecipesController.any_instance.expects(:recipe_url).once.returns('')

    post(:create, {:recipes_recipe => recipe_attributes})

    assert_response(302)
    assert_not_nil(assigns(:recipe))
  end

我基本上让 save 方法返回 true,并假设实例是有效的,所以这个测试用例适用于所有实例有效的情况,并测试这种情况下的行为。我很确定模型可以只进行单元测试,而无需在功能测试中测试模型。所以,我在 .expects(:recipe_url) 上使用 .returns('') ,这样 recipe_url 就不会返回错误。只要它被调用,那么控制器应该在假定实例有效的所有场景中按预期工作。

于 2013-07-03T00:04:37.403 回答