我正在使用Rails 5.2并进行一些测试。我正在尝试使用when(mockPersonRepository.getOne(personId)).thenReturn(person);
进行单元测试,发现ActionController::TestCase
在进入下一个测试单元方法之前没有自动重置控制器。
现在因为rails测试在每次运行时都是随机的,所以某些单元有时会失败而不是其他时间。我认为它期待HTTP 401,但我得到了200.因为控制器忽略了@controller.class.skip_before_action :verify_user
。
我可以在每个单元的末尾设置before_action :verify_user
(并且它可以工作!)但是,如果不是每次运行之前重置上下文的测试系统的代表吗?
给我一段代码:
@controller.class.before_action :verify_user
答案 0 :(得分:1)
每个测试都应该在运行后重置系统状态,这是绝对正确的。测试应该完全独立 - 这正是它们以随机顺序运行的原因(默认情况下)。
对于大多数事情 - 例如数据库事务 - 测试框架可以为您处理此问题。但是,你可以通过无限的其他方式改变环境;测试框架不能始终覆盖你的背部。
例如,如果您的测试更改了ENV
变量,该怎么办?或致电Timecop.freeze
?或者通过第二个数据库连接添加数据库记录 ?或者设置一个全局变量? ...
有时,您需要手动重置状态!
在这种情况下,我会这样做:
class ApiSiteMetricsTest < ActionController::TestCase
tests Api::SiteMetricsController
def test_1_index
@controller.class.skip_before_action :verify_user,raise: false
# ...
ensure
@controller.class.before_action :verify_user
end
end
ensure
就在那里,即使此测试失败,也应该重置状态 - 因此不会影响其他测试是否失败。
在某些情况下,您可能会发现使用MiniTest
的{{1}}和setup
方法来提供此功能非常方便。 (相当于teardown
中的before
和after
个钩子。