免责声明
这个问题是主观的。我知道应该避免在Stack上使用主观问题,但这是a)我已经苦苦挣扎了一段时间,不知道还有什么要问的; b)我认为这将被认为是一个建设性的主观问题,因此允许在堆栈上。
问题
我不知道如何测试一种便捷方法,该方法的唯一目的是在不同的对象上调用另一个方法。
据我所知,他们有两种解决方案,都有缺点:
对便捷方法及其调用的方法重新测试所有完全相同的逻辑。
测试便捷方法将调用并返回带有预期参数的原始方法。
选项1对我来说意义不大,尤其是当origin方法(便捷方法包装的方法)执行稍微复杂的逻辑并需要进行多个单元测试时,则没有意义。我为什么要在多个地方测试完全相同的逻辑?如果逻辑改变了怎么办?只在一个地方而不是多个地方进行测试会更好吗?
我倾向于选择选项2,但是明显的危险信号是您的测试实现,而不是行为。正如我一次又一次听到的(并且在大多数情况下倾向于一致),您不应该这样做。
问题示例
好,现在举一个例子来阐明我在说什么。
我目前正在研究一种API,可帮助程序员与Alexa进行交互。在我的API中设置对Alexa响应的基本方法是通过名为Alexa的类实例上的响应对象。例如,要将输出语音设置为“ hello world”,您将使用以下命令:
@alexa = Alexa.new
@alexa.response.set_speech("hello world")
除此之外,我在名为#say的Alexa类上提供了一种便捷方法,其结果完全相同:
@alexa.say("hello world")
这是幕后发生的事情:
# Alexa class
class Alexa
attr_reader :response
def initialize
@response = Response.new
end
def say(speech)
@response.set_speech(speech)
end
end
# Response class
class Response
attr_reader :response_hash
def initialize
@response_hash = {}
end
def set_speech(speech)
@response_hash[:speech] = speech
end
end
请注意,Alexa#say方法是如何包装的,他的唯一责任是使用传入的参数调用response#set_output_speech。
好,现在开始测试。
对于set_speech方法,测试很容易:
RSpec.describe Response do
describe '#set_speech' do
it 'adds the passed in argument to the response hash under key :speech' do
subject = Response.new
subject.set_speech("hello world")
expect(subject.response_hash[:speech]).to eq("hello world")
end
end
end
说方法,我被撕毁了。
我可以重新测试该方法的行为(不是DRY并导致依赖于其他方法和对象的单元测试):
RSpec.describe Alexa do
describe '#say' do
it 'adds the passed in argument to the response hash of @response under key :speech' do
subject = Alexa.new
subject.say("hello world")
expect(subject.response.response_hash[:speech]).to eq("hello world")
end
end
end
或者我可以用提供的选项测试说调用response#set_speech,据我所知,这是测试实现,而不是行为:
RSpec.describe Alexa do
describe '#say' do
it 'calls #set_speech on @response' do
subject = Alexa.new
expect(subject.response).to receive(:set_speech).with("hello world")
subject.say("hello world")
end
end
end
我的问题
TL; DR-我应该如何测试一种便捷方法,其唯一目的是调用其他方法?
重新测试行为并进行重复和相关的单元测试,还是测试便捷方法调用原始方法,从而测试实现而非行为,是否更好?
或者也许我还没有遇到第三种选择?
由于这是一个主观问题,所以我不仅仅会喜欢“使用选项1”或“使用选项2”的答案,因此请尝试解释为什么您认为一种技术比另一种更好。甚至可以从您的经历中添加一两个故事,您已经看到了一种方法相对于另一种方法的好处。谢谢!