Class AbstractPackageSanityTests

  • All Implemented Interfaces:
    junit.framework.Test

    @Beta
    @GwtIncompatible
    public abstract class AbstractPackageSanityTests
    extends junit.framework.TestCase
    Automatically runs sanity checks against top level classes in the same package of the test that extends AbstractPackageSanityTests. Currently sanity checks include NullPointerTester, EqualsTester and SerializableTester. For example:
     public class PackageSanityTests extends AbstractPackageSanityTests {}
     

    Note that only top-level classes with either a non-private constructor or a non-private static factory method to construct instances can have their instance methods checked. For example:

     public class Address {
       private final String city;
       private final String state;
       private final String zipcode;
    
       public Address(String city, String state, String zipcode) {...}
    
       @Override public boolean equals(Object obj) {...}
       @Override public int hashCode() {...}
       ...
     }
     

    No cascading checks are performed against the return values of methods unless the method is a static factory method. Neither are semantics of mutation methods such as someList.add(obj) checked. For more detailed discussion of supported and unsupported cases, see testEquals(), testNulls() and testSerializable().

    For testing against the returned instances from a static factory class, such as

     interface Book {...}
     public class Books {
       public static Book hardcover(String title) {...}
       public static Book paperback(String title) {...}
     }
     

    please use ClassSanityTester.forAllPublicStaticMethods(java.lang.Class<?>).

    If not all classes on the classpath should be covered, ignoreClasses(com.google.common.base.Predicate<? super java.lang.Class<?>>) can be used to exclude certain classes. As a special case, classes with an underscore in the name (like AutoValue_Foo) can be excluded using ignoreClasses(UNDERSCORE_IN_NAME).

    setDefault(java.lang.Class<T>, T) allows subclasses to specify default values for types.

    This class incurs IO because it scans the classpath and reads classpath resources.

    Since:
    14.0
    Author:
    Ben Yu
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static com.google.common.base.Predicate<Class<?>> UNDERSCORE_IN_NAME
      A predicate that matches classes with an underscore in the class name.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      protected void ignoreClasses​(com.google.common.base.Predicate<? super Class<?>> condition)
      Specifies that classes that satisfy the given predicate aren't tested for sanity.
      protected void publicApiOnly()
      Restricts the sanity tests for public API only.
      protected <T> void setDefault​(Class<T> type, T value)
      Sets the default value for type, when dummy value for a parameter of the same type needs to be created in order to invoke a method or constructor.
      protected <T> void setDistinctValues​(Class<T> type, T value1, T value2)
      Sets two distinct values for type.
      void testEquals()
      Tests equals() and hashCode() implementations for every top-level class in the package, that explicitly implements Object.equals(java.lang.Object).
      void testNulls()
      Performs NullPointerTester checks for all top-level classes in the package.
      void testSerializable()
      Tests all top-level Serializable classes in the package.
      • Methods inherited from class junit.framework.TestCase

        assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertEquals, assertFalse, assertFalse, assertNotNull, assertNotNull, assertNotSame, assertNotSame, assertNull, assertNull, assertSame, assertSame, assertTrue, assertTrue, countTestCases, createResult, fail, fail, failNotEquals, failNotSame, failSame, format, getName, run, run, runBare, runTest, setName, setUp, tearDown, toString
    • Method Detail

      • publicApiOnly

        protected final void publicApiOnly()
        Restricts the sanity tests for public API only. By default, package-private API are also covered.
      • testSerializable

        public void testSerializable()
                              throws Exception
        Tests all top-level Serializable classes in the package. For a serializable Class C:
        • If C explicitly implements Object.equals(java.lang.Object), the deserialized instance will be checked to be equal to the instance before serialization.
        • If C doesn't explicitly implement equals but instead inherits it from a superclass, no equality check is done on the deserialized instance because it's not clear whether the author intended for the class to be a value type.
        • If a constructor or factory method takes a parameter whose type is interface, a dynamic proxy will be passed to the method. It's possible that the method body expects an instance method of the passed-in proxy to be of a certain value yet the proxy isn't aware of the assumption, in which case the equality check before and after serialization will fail.
        • If the constructor or factory method takes a parameter that AbstractPackageSanityTests doesn't know how to construct, the test will fail.
        • If there is no visible constructor or visible static factory method declared by C, C is skipped for serialization test, even if it implements Serializable.
        • Serialization test is not performed on method return values unless the method is a visible static factory method whose return type is C or C's subtype.

        In all cases, if C needs custom logic for testing serialization, you can add an explicit testSerializable() test in the corresponding CTest class, and C will be excluded from automated serialization test performed by this method.

        Throws:
        Exception
      • testNulls

        public void testNulls()
                       throws Exception
        Performs NullPointerTester checks for all top-level classes in the package. For a class C
        • All visible static methods are checked such that passing null for any parameter that's not annotated nullable (according to the rules of NullPointerTester) should throw NullPointerException.
        • If there is any visible constructor or visible static factory method declared by the class, all visible instance methods will be checked too using the instance created by invoking the constructor or static factory method.
        • If the constructor or factory method used to construct instance takes a parameter that AbstractPackageSanityTests doesn't know how to construct, the test will fail.
        • If there is no visible constructor or visible static factory method declared by C, instance methods are skipped for nulls test.
        • Nulls test is not performed on method return values unless the method is a visible static factory method whose return type is C or C's subtype.

        In all cases, if C needs custom logic for testing nulls, you can add an explicit testNulls() test in the corresponding CTest class, and C will be excluded from the automated null tests performed by this method.

        Throws:
        Exception
      • testEquals

        public void testEquals()
                        throws Exception
        Tests equals() and hashCode() implementations for every top-level class in the package, that explicitly implements Object.equals(java.lang.Object). For a class C:
        • The visible constructor or visible static factory method with the most parameters is used to construct the sample instances. In case of tie, the candidate constructors or factories are tried one after another until one can be used to construct sample instances.
        • For the constructor or static factory method used to construct instances, it's checked that when equal parameters are passed, the result instance should also be equal; and vice versa.
        • Inequality check is not performed against state mutation methods such as List.add(E), or functional update methods such as Joiner.skipNulls().
        • If the constructor or factory method used to construct instance takes a parameter that AbstractPackageSanityTests doesn't know how to construct, the test will fail.
        • If there is no visible constructor or visible static factory method declared by C, C is skipped for equality test.
        • Equality test is not performed on method return values unless the method is a visible static factory method whose return type is C or C's subtype.

        In all cases, if C needs custom logic for testing equals(), you can add an explicit testEquals() test in the corresponding CTest class, and C will be excluded from the automated equals test performed by this method.

        Throws:
        Exception
      • setDefault

        protected final <T> void setDefault​(Class<T> type,
                                            T value)
        Sets the default value for type, when dummy value for a parameter of the same type needs to be created in order to invoke a method or constructor. The default value isn't used in testing Object.equals(java.lang.Object) because more than one sample instances are needed for testing inequality.
      • setDistinctValues

        protected final <T> void setDistinctValues​(Class<T> type,
                                                   T value1,
                                                   T value2)
        Sets two distinct values for type. These values can be used for both null pointer testing and equals testing.
        Since:
        17.0
      • ignoreClasses

        protected final void ignoreClasses​(com.google.common.base.Predicate<? super Class<?>> condition)
        Specifies that classes that satisfy the given predicate aren't tested for sanity.