lundi 1 juin 2015

Tests order dependency due to constant (final) fields

What is the recommended pattern to modify constants for unit tests? This is currently what I've used for some time and today I realized it's flawed.

Assume my class looks like this

class Foo {
   private static final int MAX_TIME = Integer.getInteger("myProp", 1000);
   ...
}

The fact that I use a VM property is not only to modify it in a unit test. It is because I want it to be immutable from the actual code and I don't want to pollute a constructor with it since it is an implementation detail.

So, in production I want a timeout of 1 second; however that's too long for unit tests so I do this

class FooTest {
   @Before
   public void setUp() {
      System.setProperty("myProp", "50");
   }
   @Test
   public void testThatAssumesTimeoutOf50() { ... }
}

This worked fine for a long time until today I finally added a BarTest like this

class BarTest {
   Foo mockFoo = mock(Foo.class); //actually done in a @Before method in the real code
}

Now what this created is that my tests fail or pass depending on the order of execution. If Foo is tested first, the test that assumes a testing timeout of 50ms passes. But if Bar is tested first then this makes Foo to be loaded due to the mock so MAX_TIME takes the default value of 1000 and then when BarTest ends and FooTest starts, the test that assumes a testing timeout of 50ms now fails.

Aucun commentaire:

Enregistrer un commentaire