Why are JUnit assert methods not generic in Java?

后端 未结 2 514
野趣味
野趣味 2021-01-18 16:34

I am using JUnit 4.12. The assert methods are not generic in nature. For instance, assertEquals method looks like:

static public void assertEquals(Object ex         


        
相关标签:
2条回答
  • 2021-01-18 17:03

    Having a generic method like this:

    <T> void assertEquals(T expected, T actual) { /* ... */ }
    

    gives you no type safety to avoid comparing unlike types: you can pass in anything to this method, since T degenerates to its upper bound, Object:

    assertEquals("string", 0);  // Compiles fine, even though they can't be equal.
    

    Ideone demo

    And nor can you use any methods on expected and actual that aren't found on Object. So, T is basically just Object.

    As such, adding generics is just over-complicating the implementation.


    Now, you could define a class like this:

    class GenericAssert<T> {
      void assertEquals(T expected, T actual) { /* ... */ }
    }
    

    and you could use this like:

    new GenericAssert<String>().assertEquals("string", 0);  // Compiler error.
    

    because you've now placed a tighter upper bound on the acceptable parameters of assertEquals, at class level.

    But this just feels a bit awkward.

    0 讨论(0)
  • 2021-01-18 17:12

    You want to look assertThat and the Hamcrest matchers; as assertThat actually works with generics:

    assertThat(String reason, T actual, Matcher<? super T> matcher) 
    

    So:

    assertEquals("abc", 123); 
    

    compiles, but fails; whereas

    assertThat(123, is("abc")); 
    

    won't even compile!

    And I am not even mentioning that asserThat calls are much better to read; and give much better information when they fail. You can even use them to compare maps, sets, whatever.

    Long story short: there is only one assert that anybody needs - assertThat that is!

    0 讨论(0)
提交回复
热议问题