我想了解使用 rspec 测试多步骤工作流的习惯用法或最佳实践。
我们以“购物车”系统为例,其中的购买流程可能是
- 当用户提交购物篮并且我们没有使用 https 时,重定向到 https
- 当用户提交购物篮并且我们使用 https 并且没有 cookie 时,创建并显示一个新的购物篮并发回 cookie
- 当用户提交到购物车并且我们使用 https 并且有一个有效的 cookie 并且新商品与第一个商品用于不同的产品时,向购物车添加一行并显示这两行
- 当用户提交到购物篮并且我们使用 https 并且有一个有效的 cookie 并且新商品与之前的商品相同时,增加该购物篮行的数量并显示这两条线
- 当用户点击购物车页面上的“结帐”并使用 https 并且有一个 cookie 并且购物车非空并且...
- ...
我读过 http://eggsonbread.com/2010/03/28/my-rspec-best-practices-and-tips/它建议 i.a 每个“it block ”应该只包含一个断言:与其进行计算然后在同一个 block 中测试多个属性,不如在上下文中使用“之前”来创建(或检索)被测对象并分配它到@some_instance_variable,然后将每个属性测试写成一个单独的 block 。这有一点帮助,但在上述情况下,测试步骤 n 需要为步骤 [1..n-1] 进行所有设置,我发现自己要么复制设置代码(显然不好),要么创建大量辅助函数名称越来越笨拙(def create_basket_with_three_lines_and_two_products)并在每个步骤的 before block 中连续调用它们。
关于如何不那么冗长/乏味地执行此操作的任何提示?我很欣赏每个示例不应依赖于先前示例留下的状态这一想法背后的一般原则,但是当您测试多步骤过程并且任何步骤都可能出错时,为每个步骤设置上下文是不可避免地需要重新运行前 n 个步骤的所有设置,所以 ...
最佳答案
这是一种可能的方法 -- 定义一个对象,该对象为每个步骤创建必要的状态,并将其传递给每个后续步骤。基本上你需要模拟/ stub 所有设置条件的方法调用:
class MultiStep
def initialize(context)
@context = context
end
def init_vars
@cut = @context.instance_variable_get(:@cut)
end
def setup(step)
init_vars
method(step).call
end
def step1
@cut.stub(:foo).and_return("bar")
end
def step2
step1
@cut.stub(:foo_bar).and_return("baz_baz")
end
end
class Cut # Class Under Test
def foo
"foo"
end
def foo_bar
"foo_bar"
end
end
describe "multiple steps" do
before(:each) do
@multi_stepper = MultiStep.new(self)
@cut = Cut.new
end
it "should setup step1" do
@multi_stepper.setup(:step1)
@cut.foo.should == "bar"
@cut.foo_bar.should == "foo_bar"
end
it "should setup step2" do
@multi_stepper.setup(:step2)
@cut.foo.should == "bar"
@cut.foo_bar.should == "baz_baz"
end
end
关于ruby - 在 rspec 中测试多步骤工作流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4430831/