Поддельные конструкторы для юнит-тестирования - PullRequest
3 голосов
/ 06 октября 2010

У меня есть набор классов, которые имеют зависимости во время создания экземпляра, то есть при создании объекта типа A он также создает другой тип B, который впоследствии создает другие типа C и т. Д.

Что касается тестирования, мне не нужна вся функциональность всех уровней для тестирования верхних, поэтому я мог бы использовать заглушки или макеты, но, поскольку у меня есть явные значения new в конструкторах, я не могу видеть прямой путькроме изменения кода для использования AbstractFactory и предоставления кода, который создает подделки во время тестирования.

Итак, есть ли «черная магия» для взлома загрузчика классов Java, поэтому вместо этого создаются поддельные классы тестированиянормальные при создании объектов с new?

Спасибо!

Ответы [ 6 ]

6 голосов
/ 06 октября 2010

Почему бы не добавить конструктор, который принимает эти зависимости в качестве параметров, вместо того, чтобы создавать их самостоятельно в конструкторе? Лично я бы добавил это и удалил другое :). Введение зависимостей делает код более простым для тестирования и более гибким в будущем (поскольку вы можете легко внедрить другую реализацию позже, не изменяя код.)

2 голосов
/ 06 октября 2010

Вы можете достичь желаемого поведения, не изменяя исходные источники, изменив путь к классам. Создайте фиктивные классы во второй исходной папке с точно такими же именами и пакетами. Затем поместите фиктивные классы в путь к классам и удалите реальные.

Это лучше всего работает с классами, которые находятся на собственной банке, так что вы можете просто обменять банки.

2 голосов
/ 06 октября 2010

То, что вы хотите, это использовать фиктивные классы. Рассмотрите возможность использования любой основы для этого. Вот хороший - https://jmockit.dev.java.net/

1 голос
/ 12 октября 2010

JMockit идеально соответствует требованиям. Например, вы можете написать такой тест:

// In production code:
public final class ClassUnderTest
{
    private final SomeDependency dep;

    public ClassUnderTest(String someData)
    {
        dep = new SomeDependency(someData);
    }

    void methodToBeTested() { ... int i = dep.doSomething("xpto", true); ... }
}

final class SomeDependency
{
    int doSomething(String s, boolean b) { ... }
}

// In test code:
public final class MyTest
{
    @Test
    public void mockingInternalDependencies()
    {
        new Expectations()
        {
            SomeDependency mockedDep;

            {
                mockedDep.doSomething(anyString, anyBoolean); result = 123;
            }
        };

        new ClassUnderTest("blah blah").methodToBeTested();
    }
}
1 голос
/ 06 октября 2010

После некоторых исследований кажется, что PowerMock может сделать это очень хорошо:

http://code.google.com/p/powermock/wiki/MockConstructor

0 голосов
/ 15 октября 2010

Другая альтернатива, как я вижу, вы не хотите ни создавать конструктор, ни использовать DI, может иметь атрибут, который вам нужно смоделировать с видимостью по умолчанию и создавать фабрики для тестирования (с тем же пакетом и в другой исходной папке). ), которые вводят непосредственно фиктивные объекты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...