RSpec:测试模型是否接收到具有特定参数的#create?

时间:2016-01-12 13:44:03

标签: ruby-on-rails ruby rspec

我刚遇到一个我正在打电话的边缘案例:

Model.create(param: derp, param2: derp2, ...)

我传入的其中一个参数错了。

我想测试一个模型正在接收调用,并传入正确的参数。

我的直觉是:

expect_any_instance_of(Model).to receive(:create).with(param: derp, param2: derp2, ...)

但是这给了:

Model does not implement #create

我传递的大部分内容都只是模型属性,我可以测试它们是否正确传递:

it "passes the derp into param" do
    expect(Model.first.param).to eq(derp)
end

然而,我传递的一个东西是attr_accessor,模型正在用after_create回调做事(这实际上是我错误传递的参数,所以在校长之外,整个测试真的是意味着那个)。

我可以像上面一样对它进行测试...查询它,确保创建完成它后面的东西,这意味着它正确地传入 - 但是当我真的只是创建功能之后我就会耦合它想要测试以确保模型在我调用create时接收到正确的参数,无论回调后发生了什么。

我在这里肯定很挑剔,但我希望我的单元测试尽可能模块化,而不是依赖其他代码。我只是想确保当我调用create时,它会收到它应该接收的数据。

我在RSpec文档中唯一能找到的是

expect(Model.count).to eq(1)

这里有什么想法吗?

编辑:谢谢大家......所有3个都是正确的。接受第一个:)这很简单,不能相信我错过了它。我实际上一开始尝试过,但是它上面有一个爆炸(!)导致它失败...需要接收(:创建!)。

3 个答案:

答案 0 :(得分:1)

我不确定这是你问题的核心,但这里有一个概念错误:

expect_any_instance_of(Model).to receive(:create).with(param: derp, param2: derp2, ...)

#create方法的接收者是class Model,而不是任何实例。以下应该完全正常:

expect(Model).to receive(:create).with(args ...)

作为一般规则,您应该避免使用expect / allow_any_instance_of,因为它通常表明您可以改进您的设计。

我希望这会有所帮助:)

答案 1 :(得分:1)

这不起作用......

expect_any_instance_of(Model).to receive(:create).with(param: derp, param2: derp2, ...

因为create不是实例方法#create,所以它是模型方法.create

你可以尝试

expect(Model).to receive(:create).with(param: derp, param2: derp2, ...)

Model.count示例只是确认记录已创建,正如您在评论中所说,无论有效参数如何,都可以创建记录。

答案 2 :(得分:1)

您正在调用expect_any_instance_of(Model)但是create是一个类函数,您可以使用:

expect(Model).to have_received(:create).with(param: derp, param2: derp2, ...)