简体   繁体   中英

How to unit test a class to check it can be used in a Set or Map (i.e. contains always works)

I discovered that some instance of a (java) class that I used in Maps and Sets sometimes fails to be found using the contains method.

The problem was simply that the class did not implement "hashCode" (but it has equals ). And the subtlety was that it actually works most of the time: I only found out about the error when running some code with concurrency.

My problem now is that I'd like to make a unit test that assert that this class can be used reliably in a Set/Map (ie that .contains works) but I cannot reproduce the bug.

As I say, almost all the time it actually works. I tried to make a Set of a couple of instances, then run multiple times contains with copies of these instances, in parallel. But it always works.

What test of mySet.contains(item-copy) would fails for sure if item class has not hashCode ?

Here is the test pseudo code that don't fails when MyItem does not implements hashCode:

def testFindInSet(): Unit ={
  val items = Seq(---list of args---).map( args => new MyItem(args)}.toSet
  items.par.foreach{ item =>
    (1 to 100).par.foreach{ k =>
      val itemCopy = new MyItem(item)  // that's a copy constructor
      assertTrue("item not found", items.contains(itemCopy))
    }
  }
}

I tried to make a Set of a couple of instances

Scala has specialized representations for sets up to 4 elements instead of using HashSet . I expect making a larger set or using HashSet explicitly should be enough to make it fail. But it's simpler just to compare hashCode of copies: assertTrue("hashCode not implemented", itemCopy.hashCode == item.hashCode) . If this fails, the contract is already broken (assuming itemCopy == item ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM