2016-07-28 48 views
5

我有一個測試類加載了一個測試spring應用程序上下文,現在我想創建一個junit規則,它將在mongo db中設置一些測試數據。爲此,我創建了一個規則類。使用spring bean的JUnit規則

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); 
     }); 
    } 
} 

現在我用我的測試類,這裏面的規則,經過mongoOperations豆。

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = SpringTestConfiguration.class) 
public class TransactionResourceTest { 

    @Autowired 
    private ITransactionResource transactionResource; 

    @Autowired 
    private MongoOperations mongoOperations; 

    @Rule 
    public MongoRule<PaymentInstrument> paymentInstrumentMongoRule 
     = new MongoRule(mongoOperations, "paymentInstrument.js", "paymentInstrument");  
.... 
} 

問題是規則在應用程序上下文被加載之前得到執行,所以mongoOperations引用被傳遞爲null。在上下文加載後有沒有辦法讓規則運行?

回答

1

這裏有一個解決方案,使用一些抽象的超類:

@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(); 
} 

然後

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

    // ... 
} 
2

據我知道你正在努力實現不是這樣直接的方式,因爲可能:

  1. 該規則在Spring的應用程序上下文之前被實例化。
  2. SpringJUnit4ClassRunner不會嘗試在規則的實例上注入任何東西。

這裏有一個替代方案在這裏描述:https://blog.jayway.com/2014/12/07/junit-rule-spring-caches/但我認爲它可能會在什麼可以加載到mongodb方面不足。

爲了實現你想要達到的目標,你可能需要一個測試執行監聽器,它會在你的規則對象中注入你需要的任何依賴關係。