2016-01-22 40 views
0

我想重构一个测试套件,这种套件的方式与实现紧密耦合,但我遇到了关系问题。例如,我有一个简单的用户模式:测试模型的关系,而不与实现耦合

class AdminUser < ActiveRecord::Base 
    belongs_to :user_role 
    delegate :executive?, to: :user_role 
end 

这是UserRole的模型:

class UserRole < ActiveRecord::Base 
    def executive? 
    name == 'Executive' 
    end 
end 

测试的UserRole的模式很容易,但是,下面的彻底检验规则,我想我也应该测试AdminUser模型,因为我期望它响应.executive ?,这就是我的问题开始的地方。

如果我遵循通常的单元测试规则,我应该只测试AdminUser,所以我可以模拟UserRole.executive?并完成它,但是...如果UserRole的实现随着时间的推移而发生变化会怎样?如果我想将UserRole更改为另一个模型或更复杂的对象以遵循更复杂的规则,该怎么办?我需要更改AdminUser的测试以遵循新的实现,并且感觉有点肮脏,因为在单元测试中肛门,我应该只测试'what',而不是'how'。

我在这里过于严格吗?有没有更好的方式来做到这一点,我不抓?

回答

1

如果您对AdminUser的实现一无所知,该怎么办?你如何知道它是否响应#executive??很简单:

expect(admin_user.respond_to?(:executive?)).to be_true 

编写另一个测试中UserRole#executive?,就大功告成了。

如果您将#executive?移出UserRole或更改其行为,当然您需要更新测试。但AdminUser的行为不会改变....或者说,它对于这个方法的行为完全由另一个类决定。在多个地方测试该方法无济于事。