dimanche 6 septembre 2015

How to inject mocks while testing to classes using CDI in production

I am programming in a Java SE environment using WELD-SE for dependency injection. Therefore dependencies of a classes look something like this:

public class ProductionCodeClass {
    @Inject
    private DependencyClass dependency;
}

When writing a unit test for this class I am creating a mock for DependencyClass and as I don't want to start a complete CDI environment for every test I run, I "inject" the mock manually:

import static TestSupport.setField;
import static org.mockito.Mockito.*;

public class ProductionCodeClassTest {
    @Before
    public void setUp() {
        mockedDependency = mock(DependencyClass.class);
        testedInstance = new ProductionCodeClass();
        setField(testedInstance, "dependency", mockedDependency);
    }
}

The statically imported method setField() I have written myself in a class with tools I use in testing:

public class TestSupport {
    public static void setField(
                                final Object instance,
                                final String field,
                                final Object value) {
        try {
            for (Class classIterator = instance.getClass();
                 classIterator != null;
                 classIterator = classIterator.getSuperclass()) {
                try {
                    final Field declaredField =
                                classIterator.getDeclaredField(field);
                    declaredField.setAccessible(true);
                    declaredField.set(instance, value);
                    return;
                } catch (final NoSuchFieldException nsfe) {
                    // ignored, we'll try the parent
                }
            }

            throw new NoSuchFieldException(
                      String.format(
                          "Field '%s' not found in %s",
                          field,
                          instance));
        } catch (final RuntimeException re) {
            throw re;
        } catch (final Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}

What I don't like about this solution is, that I need this helper over and over in any new project. I already packaged it as a maven project I can add as a test dependency to my projects.

But isn't there something ready made in some other common library I am missing? Any comments on my way of doing this in general?

Aucun commentaire:

Enregistrer un commentaire