由于ActiveRecord :: StatementInvalid:error,无法测试控制器渲染

时间:2016-12-22 12:19:50

标签: ruby-on-rails activerecord rspec

好的,我有这个控制器代码:

def create
    @foo = Foo.new(user: User.new(user_params))
    if @foo.save
      redirect_to foos_path
    else
      render :new
    end
end

我想测试当用户电子邮件无效时是否重新呈现新页面。为此,我创建了这个测试:

it "should re-render the new template" do
    post :create, params: { user: attributes_for(:user, email: "abc.com") } }
    expect(response).to render_template(:new)
end

但是,由于此错误,测试失败:

 Failure/Error: if @foo.save

 ActiveRecord::StatementInvalid:
   PG::NotNullViolation: ERROR:  null value in column "user_id" violates not-null constraint
   DETAIL:  Failing row contains (260, null).
   : INSERT INTO "foos" DEFAULT VALUES RETURNING "id"

Foo表有一个

t.belongs_to :user, null: false, index: true

所以没有用户就不会添加foo。

我认为此错误实际上是一种理想的行为,因为它可以防止在没有用户的情况下保存foo,并且用户无法使用无效的电子邮件进行保存。但是我仍然需要测试它,所以我测试错了吗?我怎样才能做到这一点?有什么错过了吗?

提前致谢!

2 个答案:

答案 0 :(得分:1)

你的问题不是很清楚,但我想这里是错误:

tf.nn.sparse_softmax_cross_entropy_with_logits

@foo = Foo.new(user: User.new(user_params)) 不会将用户保存到数据库,因此您将没有ID,并且将失败您的user_id非空约束。

使用:

User.new

代替

答案 1 :(得分:0)

您可以尝试:

@foo = Foo.new
@foo.build_user(user_params)
@foo.save

它应该同时保存用户和foo。

这将创建一个事务,以便在验证foo和user之前不会将任何记录保存到数据库。