我想使用rspec对RoR进行单元测试,并使用如下方法:
def create_record(obj, params)
begin
obj.add_attributes(params)
result = obj.save
rescue
MyMailer.failed_upload(@other_var, obj.api_class_name, params).deliver_now
end
end
create_record
永远不会直接调用,而是通过另一种适当填充@other_var
的方法调用。
我应该如何测试代码以确保正确调用MyMailer?我应该将@other_var
传递给方法,而不是依赖它在其他地方填充(也就是说:这是代码味道吗?)?谢谢!
答案 0 :(得分:0)
在Ruby中,您可以使用Object#instance_variable_set
来设置任何实例变量。
RSpec.describe Thing do
describe "#create_record" do
let(:thing) do
t = Thing.new
t.instance_variable_set(:@other_var, "foo")
t
end
# ...
end
end
这完全绕过了任何封装,这意味着instance_variable_set
的使用可以被视为代码气味。
另一种选择是使用RSpecs模拟和存根设施,但是对测试中的实际对象进行存根也是一种代码味道。
您可以通过将依赖项作为参数或构造函数注入传递来避免这种情况:
class Thing
attr_accessor :other_var
def initialize(other_var: nil)
@other_var = other_var
end
def create_record(obj, attributes)
# ...
end
end
一个好的模式是service objects。