2 Replies Latest reply: Oct 7, 2011 10:44 AM by 836522 RSS

    Unit testing: Mocking custom classes with null

    836522
      Hi,

      I was trying to save time on testing the usual hashCode() and equals() methods so I got this class: http://www.cornetdesign.com/files/BeanTestCase.java.txt

      I altered it a bit as it wasn't handling standard classes only primitives.

      Anyway, I got to the point to include my own custom classes.
      I have to create a 'mock' object for my class properties, e.g. field.getType().newInstance()

      Fine, but there are some tricky instances. E.g. when I'd like to create an instance of java.net.URL which takes a URL as String in the constructor.
      This is almost impossible to automate as it has to be a valid URL format not just a random String.

      So, I thought I set them to null, e.g.

      assertTrue(o1.equals(o2))

      as both properties are null.

      Is this the right approach you think?

      I welcome any suggestions.

      My initial idea was to save enormous amount of time automating the hashCode() and equals() method tests as they took so long to write.

      Thanks
        • 1. Re: Unit testing: Mocking custom classes with null
          836522
          OK, this is now a question as when I do a Cobertura coverage obviously this happens:


          result = prime * result + ((users == null) ? 0 : users.hashCode());


          users IS null so the 1st condition gets tested but not the 2nd one.


          So, how could I mock my objects when they have unknown requirements in their constructor?
          • 2. Re: Unit testing: Mocking custom classes with null
            452196
            Trouble would be that you are only testing the null branch of the equals or hashCode, which typically have to check for null, then if not null do an actual comparison.

            It's worth the effort of learning to use a package such as EasyMock to create and program mock objects. It's tidiier if you are progamming to interfaces, however, but it will mock ordinary objects, though probably not if they are final.

            What you could do is to define a factory interface, and have a table of anonymous classes wich generate various types. In effect create a library of dumy object factories.

            Something like:
            private interface DummyGenerator {
                  Object generate(int idx);
            
                  Class<?> getType();
            }
            
            private final static DummyGenerator[] generatorsTable {
                new DummyGenerator() {
                       public Object generate(int idx) {
                         return new URL("http://nowhere.com/" + idx);
                      }
                 public Class<?> getType() { return URL.class; }
                }.
            .. generators for other classes
            }
            
            private final static Map<Class<?>, DummyGenerator> genMap = new HashMap<Class<?>, DummyGenerator>(generatiorsTable.length);
            
            static {
                for(DummyGenerator gen : generatorsTable) 
                    genMap.put(gen.getType(), gen);
            }