keeganwitt / gmock

Automatically exported from code.google.com/p/gmock
6 stars 2 forks source link

Provide default behavior for equals, hashCode, toString #61

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
We should provide a default behavior for equals, hashCode, toString

This tests should pass:

def key1 = mock()
play {
  [:].put(key1, "value1")
}
_________________

def key1 = mock()
def key2 = mock()
play {
  assertFalse key1 == key2
}
_________________

def key1 = mock()
play {
    assertNotNull key1.toString()
}

Original issue reported on code.google.com by julien.g...@gmail.com on 6 Feb 2009 at 9:43

GoogleCodeExporter commented 9 years ago

Original comment by julien.g...@gmail.com on 6 Feb 2009 at 9:49

GoogleCodeExporter commented 9 years ago
That means the users can never mock that methods?

Original comment by JohnnyJianHY on 6 Feb 2009 at 9:58

GoogleCodeExporter commented 9 years ago
IMO, if users have not mock these methods, we should provide some default 
behaviors,
otherwise do not provide.

For example, when user mock the hashCode() method, that means he only expect 
this
method once, so we should not provide default behavior after his expectation is
matched, that is, the following test should pass:

def mock = mock()
mock.hashCode().returns(1)
play {
  assertEquals 1, mock.hashCode()
  shouldFail {
    mock.hashCode()
  }
}

Right?

Original comment by JohnnyJianHY on 6 Feb 2009 at 3:49

GoogleCodeExporter commented 9 years ago
I have thought it over, and there are 4 choices:

1. as I said, we provide default behaviors if users have not mocked these 
methods,
otherwise do not provide.

2. always provide default behaviors and do not allow users to mock these 
methods.

3. always provide default behaviors but users can still mock these methods, 
that is,
the following test should pass:

def mock = mock()
mock.hashCode().returns(1)
play {
  assertEquals 1, mock.hashCode()
  assertEquals System.identityHashCode(mock), mock.hashCode() // default behavior
}

4. introduce an "entire mock" which do not provide any default behaviors, while 
the
normal mock is as described in 3) (that is, the above test should pass). The 
entire
mock may look like:

def mock = entire(mock())
play {
  shouldFail {
    mock.hashCode() // no default behavior here
  }
}

Any thought?

Original comment by JohnnyJianHY on 7 Feb 2009 at 8:11

GoogleCodeExporter commented 9 years ago
I think 1 is what would make the most sense for users. Most of the time they 
don't
care about hashcode being called but if they start needing any mocking on it 
then we
should stop providing any default. The same idea should be valid for equals and 
toString.

So 1! and I think that what easymock is following.

So this should be a valid test:
def mock = mock()
mock.hashCode().returns(1)
play {
  assertEquals 1, mock.hashCode()
  shouldFail {
    mock.hashCode()
  }
}

Original comment by julien.g...@gmail.com on 7 Feb 2009 at 9:12

GoogleCodeExporter commented 9 years ago
But there will be no chance for the users to mock these methods and reserve the
default behaviors at the same time.

Original comment by JohnnyJianHY on 7 Feb 2009 at 11:36

GoogleCodeExporter commented 9 years ago
That's correct. When someone start setting up expectation on hashCode he remove 
all
default behavior. 

For 95% of usages the default will be fine and that what users expect. I can see
mocking hashcode only in really specific scenario where users would have full 
control
of it with no default.

Original comment by julien.g...@gmail.com on 7 Feb 2009 at 11:45

GoogleCodeExporter commented 9 years ago
OK then.

Original comment by JohnnyJianHY on 7 Feb 2009 at 12:10

GoogleCodeExporter commented 9 years ago

Original comment by JohnnyJianHY on 10 Feb 2009 at 7:48

GoogleCodeExporter commented 9 years ago

Original comment by JohnnyJianHY on 10 Feb 2009 at 11:28