2016-07-28 12 views
5

Mam klasę testową, która ładuje kontekst aplikacji testowej sprężyny, teraz chcę utworzyć regułę junit, która ustawi niektóre dane testowe w mongo db. W tym celu stworzyłem klasę reguł.Reguła JUnit używająca fasoli sprężynowej

public class MongoRule<T> extends ExternalResource { 

    private MongoOperations mongoOperations; 
    private final String collectionName; 
    private final String file; 

    public MongoRule(MongoOperations mongoOperations, String file, String collectionName) { 
     this.mongoOperations = mongoOperations; 
     this.file = file; 
     this.collectionName = collectionName; 
    } 

    @Override 
    protected void before() throws Throwable { 
     String entitiesStr = FileUtils.getFileAsString(file); 
     List<T> entities = new ObjectMapper().readValue(entitiesStr, new TypeReference<List<T>>() { 
     }); 
     entities.forEach((t) -> {    
      mongoOperations.save(t, collectionName); 
     }); 
    } 
} 

Teraz używam tej reguły w mojej klasie testowej i przekazywaniu fasoli mongoOperations.

Problem polega na tym, że Reguła jest wykonywana przed załadowaniem kontekstu aplikacji, więc odwołanie do pliku mongoOperations jest przekazywane jako puste. Czy istnieje sposób, aby reguły były uruchamiane po załadowaniu kontekstu?

Odpowiedz

1

Oto rozwiązanie, używając jakiejś abstrakcyjnej klasie Super:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = SpringTestConfiguration.class) 
public abstract class AbstractTransactionResourceTest<T> { 

    @Autowired 
    private ITransactionResource transactionResource; 

    @Autowired 
    private MongoOperations mongoOperations; 

    @Before 
    public void setUpDb() { 
     String entitiesStr = FileUtils.getFileAsString(entityName() + ".js"); 
     List<T> entities = new ObjectMapper().readValue(entitiesStr, new TypeReference<List<T>>() {}); 
     entities.forEach((t) -> {    
      mongoOperations.save(t, entityName()); 
     }); 
    }  

    protected abstract String entityName(); 
} 

następnie

public class TransactionResourceTest extends AbstractTransactionResourceTest<PaymentInstrument> { 
    @Override 
    protected String entityName() { 
     return "paymentInstrument"; 
    }; 

    // ... 
} 
2

O ile wiem, co staramy się osiągnąć nie jest możliwe w tak prosty sposób, ponieważ:

  1. Reguła jest tworzona przed kontekstem aplikacji wiosennej.
  2. SpringJUnit4ClassRunner nie będzie próbował wstrzyknąć niczego w instancji reguły.

Istnieje alternatywa opisana tutaj: https://blog.jayway.com/2014/12/07/junit-rule-spring-caches/, ale myślę, że nie spełniłaby tego, co można załadować do mongodb.

Aby osiągnąć to, co chcesz osiągnąć, prawdopodobnie będziesz potrzebował detektora wykonania testu, który wprowadziłby dowolne zależności wymagane dla obiektu reguły.