Test many conditions using mocha

174 views Asked by At

What's the best way to test methods like the following using mocha gem?

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

Is a best practice to test "AND" and "OR" conditions? Should I create many tests to cover all possibilities or one expects options to cover all?


I'm using rails 4 + test unit.

When i have tests only with &&, for instance:

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

I'm testing:

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

The problem is when I have "OR" conditions. With the first method ( can_create? ) I can't do that:

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)

Because ( owner? and member? methods can be true/false ).

1

There are 1 answers

0
joel1di1 On BEST ANSWER

My first guess is to write several tests:

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

Then you can refactor you tests to have something cleaner, so you want to use stubs instead of expects to avoid the OR problem:

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

after all, it's not so long for this example. If you have lots and lots of conditions, you might want something like Aupajo. But I think you'll end to write your own, since you will have some specifics needs.

regards