2015-03-22 2 views
1

В более сложных модульных тестах мне часто требуется наличие определенного набора правил. Некоторые из этих правил имеют зависимости от другого. Поскольку упорядочение имеет значение, для этого я использую RuleChains. Все хорошо до сих пор.Агрегация правил JUnit с зависимостями между собой

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

То, что я хотел бы иметь это Правила Правил, т.е. (предопределенный) Правило, которое содержит или агрегаты других (применение & тестов специфических) Правила.

Я приведу пример того, как это в настоящее время выглядит следующим образом:

public LoggingRule logRule = new LogRule(); 
public ConfigurationRule configurationRule = new ConfigurationRule(); 
public DatabaseConnectionRule dbRule = new DatabaseConnectionRule(); 
public ApplicationSpecificRule appRule = new ApplicationSpecificRule(); 

@Rule 
RuleChain chain = RuleChain.outerRule(logRule) 
          .around(configurationRule) 
          .around(dbRule) 
          .around(appRule); 

Предположим, что данные правила зависят друг от друга, например, ApplicationSpecificRule требует, чтобы DatabaseConnectionRule был выполнен первым, чтобы установить соединение, ConfigurationRule инициализировал пустую конфигурацию и т. д. Также предположим, что для этого (довольно сложного теста) на самом деле требуются все правила.

Единственное решение, которое я мог придумать до сих пор является создание фабричных методов, которые возвращают предопределенный RuleChain:

public class ApplicationSpecificRule extends ExternalResource 
{ 
    public static RuleChain basicSet() 
    { 
     return RuleChain.outerRule(new LogRule()) 
         .around(new ConfigurationRule()) 
         .around(new DatabaseConnectionRule()) 
         .around(new ApplicationSpecificRule()); 
    } 
} 

В тесте это может быть использовано следующим образом:

@Rule 
RuleChain chain = ApplicationSpecificRule.basicSet(); 

При этом дублирование удаляется, и дополнительные правила могут быть легко интегрированы. Можно даже добавить к этому RuleChain определенные для тестирования правила. Однако нельзя получить доступ к содержащимся правилам, когда они необходимы для дополнительной настройки (предположим, что вам нужен ApplicationSpecificRule для создания какого-либо объекта домена и т. Д.).

В идеале это расширение будет также поддерживаться с использованием других предопределенных наборов, например. a advandancedSet, который строится поверх basicSet правил.

Можно ли это как-то упростить? Является ли это хорошей идеей в первую очередь или я как-то злоупотребляю правилами? Помогло бы это реструктурировать тесты? Мысли?

ответ

1

Интерфейс TestRule имеет только один метод, так что это довольно легко может определить собственное правило, что делегаты на RuleChain и хранят ссылки на другие правила:

public class BasicRuleChain implements TestRule { 
    private final RuleChain delegate; 
    private final DatabaseConnectionRule databaseConnectionRule 
     = new DatabaseConnectionRule(); 

    public BasicRuleChain() { 
    delegate = RuleChain.outerRule(new LogRule()) 
     .around(new ConfigurationRule()) 
     .around(databaseConnectionRule) 
     .around(new ApplicationSpecificRule()); 
    } 

    @Override 
    public Statement apply(Statement base, Description description) { 
    return delegate.apply(base, description 
    } 

    public Connection getConnection() { 
    return databaseConnectionRule.getConnection(); 
    } 
} 
+0

Да, это хорошая идея. Вероятно, у меня не будет того, что мой «RuleChain» предоставит определенные методы из внутренних используемых «правил», но сделает сами «Правила» доступными. Таким образом, мне не придется расширять «BasicRuleChain» для каждого дополнительного варианта использования. – geld0r

1

Не становится намного проще, чем это, не так ли? Единственное, что сделало бы его еще проще, - просто использовать экземпляр вместо фабрики, так как вам не нужны свежие экземпляры все время.

+0

Хорошего предложение об экземпляре против завода. Как бы вы хотели получить доступ к содержащимся правилам? – geld0r

+0

Вы определенно не хотите использовать экземпляр. Некоторые правила имеют внутреннее состояние, которое не должно использоваться совместно с другими тестами. – NamshubWriter

Смежные вопросы