hazendaz / javabean-tester

JavaBean Tester
http://codebox.org.uk/pages/articles/unit-testing-javabeans
Apache License 2.0
9 stars 5 forks source link

serializable is only a one way test and not complete #28

Open hazendaz opened 7 years ago

hazendaz commented 7 years ago

Because serialization will work if the object attempting to be serialized is serialized, it does nothing to confirm the underlying objects themselves are serializable. If a field for example is transient but nothing is defined to restore it such as List, then it won't be restored. We should look to enhance this so we can test the contents written are the contents retrieved.

Sample code I used to visually confirm a problem which could be basis for this. This uses mybatis CacheKey as there were questions regarding List and scanners stating not serializable. After testing it was determined that it is serializable if contents themselves are. If the contents is just another bland object, then it is not. However, marking the class transient actually causes a problem resulting in the data being null entirely when reading back the object as it will never be written.

  @Test
  public void serializationTest() {
      CacheKey cacheKey = new CacheKey();
      cacheKey.update(new Object());
      canSerialize(cacheKey);
  }

  void canSerialize(final CacheKey object) {
      ObjectOutputStream output = null;
      try {
          FileOutputStream fout = new FileOutputStream("address.ser");
          output = new ObjectOutputStream(fout);
          output.writeObject(object);
      } catch (final IOException e) {
          Assert.fail(String.format("An exception was thrown while serializing the class '%s': '%s',", object
                  .getClass().getName(), e.toString()));
      } finally {
          if (output != null) {
              try {
                  output.close();
              } catch (IOException e) {
                  Assert.fail(String.format("An exception was thrown while closing stream for class '%s': '%s',",
                          object.getClass().getName(), e.toString()));
              }
          }
      }

      ObjectInputStream input = null;
      try {
          FileInputStream fin = new FileInputStream("address.ser");
          input = new ObjectInputStream(fin);
          CacheKey readCache = (CacheKey) input.readObject();
          int count = readCache.getUpdateCount();
      } catch (Exception e) {
          Assert.fail(String.format("An exception was thrown while serializing the class '%s': '%s',", object
                  .getClass().getName(), e.toString()));
      } finally {
          if (input != null) {
              try {
                  input.close();
              } catch (IOException e) {
                  Assert.fail(String.format("An exception was thrown while closing stream for class '%s': '%s',",
                          object.getClass().getName(), e.toString()));
              }
          }
      }
  }
hazendaz commented 7 years ago

Added code that covers this but testing is very weak at best.

Need to properly name objects a bit better.

Need to have one that has a transient List so that it breaks as that is the use case for deserialization as it will serialize fine but will lose data if populated.

Keeping this open until tests can be further refined and cleaned up. Code is solid and has been adjusted per guidence given over on mybatis.