我有下一个场景:
module Module
class CommandPattern
def initialize(value)
command = []
@var = value['something']
@abc = value['abc']
@command << value
end
def add(value)
@command << value
end
def get_command
@command
end
end
end
module Module
class Implementator
def initialize(value)
@value = value
end
def method_to_test(argument)
var = "command1"
cmd = CommandPattern.new(var)
var2 = "command2"
cmd.add(var2)
var3 = argument
cmd.add(var3)
commands = var + var2 + var3
commands
end
end
end
所以,当我测试Module :: B.method_I_want_to_test时,模拟“var = A.new(some_stuff)”的最佳做法是什么?除了重构并将这一行移到单独的方法之外,还有一些很好的方法吗?
关于这个问题的一点背景 - 这个样式(Module :: ClassA和Module :: ClassB) - 我正在使用http://naildrivin5.com/gli/,这个方法的原因是A类实际上是在实现Command Pattern。 / p>
所以问题显然是由于错误的方式尝试编写规范。
我之前做的是(在@spickermann建议的路上):
RSpec.describe Module::Implementator do
describe "#method_to_test" do
let(:command_argument) { "command" }
let(:cmnd) { double(CommandPattern, :new => command_argument, :add => command_argument)}
subject(:method_to_test) do
Implementator.new("value").method_to_test("dejan")
end
before do
allow(CommandPattern).to receive(:new).with(any_args).and_return(cmnd)
allow(CommandPattern).to receive(:add).with(any_args).and_return(cmnd)
end
it 'does something' do
expect{ method_to_test }.not_to raise_error
end
it 'does something else' do
result = method_to_test
expect(result).to eq("command1command2dejan")
end
end
end
问题显然是在测试Module :: Implementator,没有意识到我可以在我的RSpec.describe块周围放置模块并解决我的第一个问题:
module Module
RSpec.describe Implementator do
describe "#method_to_test" do
let(:command_argument) { "command" }
let(:cmnd) { double(CommandPattern, :new => command_argument, :add => command_argument)}
subject(:method_to_test) do
Implementator.new("value").method_to_test("dejan")
end
before do
allow(CommandPattern).to receive(:new).with(any_args).and_return(cmnd)
allow(CommandPattern).to receive(:add).with(any_args).and_return(cmnd)
end
it 'does something' do
expect{ method_to_test }.not_to raise_error
end
it 'does something else' do
result = method_to_test
expect(result).to eq("command1command2dejan")
end
end
end
end
我遇到的另一个问题是保持YAML结构的全局变量,我错过了在spec_helper.rb中看到并声明
但是,感谢@ spickermann的建议,问题解决了。
答案 0 :(得分:1)
我会从这样的事情开始:
describe '#method_I_want_to_test' do
let(:something) { # whatever something needs to be }
let(:a) { double(A, # methods you need from a) }
subject(:method_I_want_to_test) do
B.new(something).method_I_want_to_test
end
before do
allow(A).to receive(:new).with(something).and_return(a)
end
it 'does what I expect' do
expect(method_I_want_to_test).to eq(# what do_semething_else returns)
end
end
有趣的部分是before
块,它在new
上存根A
方法。它始终返回let(:a)
行中定义的double,而不是A