That's not about how to write tests, but about techniques which allows to overcome some very bad coding practices in case you are not allowed to modify code base (as my team was put in such restrictions).
Let's start with such a pearl: private static initialized members (we will skip the thread safety aspects and concentrate on instance member only).
package org.example; public class SomeStaticUtil { private static SomeStaticUtil instance = SomeStaticUtil.getInstance(); public static SomeStaticUtil getInstance() { if( instance == null ) { instance = new SomeStaticUtil(); } return instance; } }So how to substitute SomeStaticUtil with different implementation suitable for testing scenarios (aka mocks)? Remember, you are not allowed to modify the code (I would love to). There are few ways to do that:
- Excellent PowerMock framework. Didn't fit this project because bytecode manipulations crashed JVM.
- Magnificent AspectJ framework. Didn't fit this project because of complex aspects and necessary runtime weaving.
- Old and well-known reflection :-)
So what we can do here? Let's us exploit two excellent and very powerful test scaffolding frameworks: Mockito and Spring Test. Here is what we can do:
package org.example; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.springframework.test.util.ReflectionTestUtils; public class SomeStaticUtilTestCase { private SomeStaticUtil someStaticUtil; @Before public void setUp() { someStaticUtil = Mockito.mock( SomeStaticUtil.class ); ReflectionTestUtils.setField( someStaticUtil, "instance", someStaticUtil ); } @Test public void someTest() { // ... some tests } }Very simple but powerful: replace private static member instance with mock implementation. Cool.
No comments:
Post a Comment