[英]Testing: Stub model methods or not?
我进行两种测试:单元测试和集成测试(对于后者,则为Cucumber / Capybara)。
对于单元测试,我想知道在测试其他类时是否存根/模拟模型方法是否是最佳实践?
# model
class Price < ActiveRecord::Base
belongs_to :price_type, inverse_of: :prices
belongs_to :book, inverse_of: :prices
scope :for_book, ->(book) { where("book_id = ?", book) }
scope :for_price_type, ->(price_type) { where("price_type_id = ?", price_type) }
def self.latest_book_url(book, competitor)
latest_price = for_book(book).for_competitor(competitor).last
latest_price ? latest_price.book_url : nil
end
end
如果我测试了调用这些作用域的类或类方法latest_book_url
,则应该模拟/存根模型的作用域和方法,还是使用FactoryGirl保存记录,然后在测试中调用模型上的方法?
# class to be tested
class PriceLister
def initialize(book)
@book = book
@competitors = book.competitors
@price_types = PriceType.all
end
def list_book_urls_by_competitor
price_list = {}
@competitors.each do |competitor|
price_list[competitor] = {}
price_list[competitor][:book_url] = Price.latest_book_url(@book, competitor)
@price_types.each do |price_type|
price_list[competitor][price_type] = Price.for_book(@book).for_competitor(competitor).for_price_type(price_type).last
end
end
price_list
end
end
按照定义,单元测试是单个代码单元的测试。 如果您不是在模拟/测试,那么您是在测试单个单元还是在进行小型集成测试? 最佳做法是模拟/存根进行单元测试
假设您仍然在谈论第二个问题的单元测试,那么是的,现在您应该模拟/存根已经测试过的代码。
原因很简单。 如果更改代码并破坏测试,则希望尽可能缩小导致问题的代码的范围。 如果您因为许多测试都调用相同的代码而破坏了许多测试,那么突然您将有许多测试要签出。 如果您在所有其他测试中都嘲笑了该调用,那么只有真正测试该单元的测试才会失败,而依赖于该单元的测试才能正常运行。
认为它是一个假设。 如果您假设您的方法有效,因为该方法的单元测试正在运行,并且其他工作都基于该假设,那么一切都很好,直到证明该假设是错误的为止。 那时一切都崩溃了。 另一方面,如果您认为该方法将是错误的,而是用已知结果(例如,模拟方法给出的固定结果)替换该方法,则您的其他代码将与该问题隔离。
在单元测试中,可以在测试PriceLister时从Price中提取方法。 对于Price方法,应该有单独的单元测试。
而且您的集成测试应该测试整个终端功能,而无需进行任何测试
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.