使用mocha测试许多条件

时间:2013-08-27 23:20:29

标签: ruby-on-rails ruby mocha

使用mocha gem测试如下方法的最佳方法是什么?

def can_create?(user)
  opened? && (owner?(user) || member?(user))
end

测试“AND”和“OR”条件是最佳做法吗?我是否应该创建许多测试以涵盖所有可能性,或者是否期望覆盖所有可能的选项?


我正在使用rails 4 +测试单元。

当我只使用&&和测试时,例如:

def can_update?(user)
  opened? && owner?(user)
end

我正在测试:

group = Group.new
user  = User.new
group.expects(:opened?).returns(true)
group.expects(:owner?).returns(true)
assert group.can_update?(user)

问题是当我有“或”条件时。使用第一种方法(can_create?)我不能这样做:

group = Group.new
user  = User.new
group.expects(:opened?).returns(true)
group.expects(:owner?).returns(true)
group.expects(:member?).returns(true)
assert group.can_create?(user)

因为(所有者?和成员?方法可以是真/假)。

1 个答案:

答案 0 :(得分:0)

我的第一个猜测是写几个测试:

test 'with opened and owner' do
  group = Group.new
  user  = User.new
  group.expects(:opened?).returns(true)
  group.expects(:owner?).returns(true)
  assert group.can_create?(user)
end

test 'with opened and member' do
  group = Group.new
  user  = User.new
  group.expects(:opened?).returns(true)
  group.expects(:owner?).returns(false)
  group.expects(:member?).returns(true)
  assert group.can_create?(user)
end

test 'with opened and not member or owner' do
  group = Group.new
  user  = User.new
  group.expects(:opened?).returns(true)
  group.expects(:owner?).returns(false)
  group.expects(:member?).returns(false)
  assert group.can_create?(false)
end

然后你可以重构测试以获得更清晰的东西,所以你想使用存根而不是期望避免OR问题:

def assert_can_create(params, expected)
  group = Group.new
  user  = User.new
  group.stubs(:opened?).returns(params[:opened])
  group.stubs(:owner?).returns(params[:owner])
  group.stubs(:member?).returns(params[:member])

  assert group.can_create?(expected)
end

test 'can_create possibilities' do
  assert_can_create({opened: true, owner: true, member:true}, true)
  assert_can_create({opened: true, owner: true, member:false}, true)
  assert_can_create({opened: true, owner: false, member:true}, true)
  assert_can_create({opened: true, owner: false, member:false}, false)
  assert_can_create({opened: false, owner: true, member:true}, false)
  [...]
end

毕竟,这个例子不是很长。如果你有很多很多条件,你可能想要像Aupajo这样的东西。但我认为你最终会写自己的,因为你会有一些具体的需求。

问候