2013-07-17 2 views
2

DbUnit을 사용하여 통합 테스트를 실행해야합니다. 데이터 세트 (테스트 전후)를 작성하여 @DatabaseSetup@ExpectedDatabase 주석을 사용하여 비교했습니다. 테스트하는 동안 하나의 새로운 데이터베이스 행이 생성되었습니다 (애프터 테스트 데이터 세트에 표시됩니다. @ExpectedDatabase 주석을 사용하여 지정합니다). 문제는 행 ID가 자동으로 생성된다는 것입니다 (최대 절전 모드를 사용하고 있습니다). 그래서 행 ID가 영구적으로 변경됩니다. 따라서 테스트가 끝난 후 한 번만 테스트를 통과 한 후에 테스트 데이터 세트에서 ID를 변경해야하지만, 필요하지는 않습니다. DbUnit으로이 문제를 해결할 수 있다면이 문제에 대한 해결책을 알려주십시오.DbUnit 자동 생성 ID 확인

+0

비슷한 문제가 발생했습니다. 문제를 해결하기 위해 해결책을 찾았습니까? – ReturnHttp402

+0

ID 주장을 무시했습니다. 솔루션 B (아래 답변)를 참조하십시오. 내 테스트의 경우 이러한 주장은 필수적인 것은 아닙니다. – mvb13

+0

어설 션에 assertEqualsIngoreColumns()를 어떻게 통합합니까? btw, 나는 또한 데이터 소스에 연결된 데이터베이스를 사용하여 데이터베이스를 연결하는 것이 선택의 여지가 있음을 발견했다 - 메모리 db는 테스트를 실행할 때마다 초기화를 수행합니다. – ReturnHttp402

답변

2

솔루션 A :

를 사용하여 할당 된 ID 전략과 비즈니스 로직에서 다음 값을 검색하기 위해 별도의 쿼리를 사용합니다. 그래서 당신은 언제나 적절한 데이터베이스 정리로 영속성 테스트에서 알려진 ID를 할당 할 수 있습니다. 이것은 Oracle Sequence를 사용하는 경우에만 작동합니다.

솔루션 B :

제가 잘못 본게 아니라면, org.dbunit.Assertion에서 assertEqualsIngoreColumns()와 유사한 몇 가지 방법이 있습니다. 그래서 아이디 어설 션을 무시할 수 있습니다. 보통은 ID가 null이 아닌지 확인하여 보상 할 것입니다. 어쩌면 @ExpectedDatabase에 몇 가지 옵션이 있지만 확실하지 않습니다.

솔루션 C :

내가 용액 B는 약간의 테스트 커버리지를 희생하면서 그 용액 A는 약간의 성능 오버 헤드를 소개하기 때문에 더 나은 솔루션이 있는지 알고 싶습니다.

현재 사용중인 dbunit의 버전입니다. 2.4.9에서 이러한 주석을 본 적이 없으며 사용하기가 더 쉬워 보입니다.

0

이 해결 방법은 지금까지 내 피부를 절약 :

나는 대체 기능이있는 AbstractDataSetLoader 구현이와

public class ReplacerDataSetLoader extends AbstractDataSetLoader { 
    private Map<String, Object> replacements = new ConcurrentHashMap<>(); 

    @Override 
    protected IDataSet createDataSet(Resource resource) throws Exception { 
     FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder(); 
     builder.setColumnSensing(true); 
     try (InputStream inputStream = resource.getInputStream()) { 
      return createReplacementDataSet(builder.build(inputStream)); 
     } 
    } 

    /** 
    * prepare some replacements 
    * @param dataSet 
    * @return 
    */ 
    private ReplacementDataSet createReplacementDataSet(FlatXmlDataSet dataSet) { 
     ReplacementDataSet replacementDataSet = new ReplacementDataSet(dataSet); 

     //Configure the replacement dataset to replace '[null]' strings with null. 
     replacementDataSet.addReplacementObject("[null]", null); 
     replacementDataSet.addReplacementObject("[NULL]", null); 
     replacementDataSet.addReplacementObject("[TODAY]", new Date()); 
     replacementDataSet.addReplacementObject("[NOW]", new Timestamp(System.currentTimeMillis())); 

     for (java.util.Map.Entry<String, Object> entry : replacements.entrySet()) { 
      replacementDataSet.addReplacementObject("["+entry.getKey()+"]", entry.getValue()); 
     } 
     replacements.clear(); 

     return replacementDataSet; 
    } 

    public void replace(String replacement, Object value){ 
     replacements.put(replacement, value); 
    } 
} 

어떻게 든 당신이 필요로하는 ID를 추적하고 고환에서 대체 할 수있는을

@DatabaseSetup(value="/test_data_user.xml") 
@DbUnitConfiguration(dataSetLoaderBean = "replacerDataSetLoader") 
public class ControllerITest extends WebAppConfigurationAware { 

    //reference my test dbconnection so I can get last Id using regular query 
    @Autowired 
    DatabaseDataSourceConnection dbUnitDatabaseConnection; 
    //reference my datasetloader so i can iteract with it 
    @Autowired 
    ColumnSensingFlatXMLDataSetLoader datasetLoader; 


    private static Number lastid = Integer.valueOf(15156); 
    @Before 
    public void setup(){ 
     System.out.println("setting "+lastid); 
     datasetLoader.replace("emp1", lastid.intValue()+1); 
     datasetLoader.replace("emp2", lastid.intValue()+2); 
    } 

    @After 
    public void tearDown() throws SQLException, DataSetException{ 
     ITable table = dbUnitDatabaseConnection.createQueryTable("ids", "select max(id) as id from company.entity_group"); 
     lastid = (Number)table.getValue(0, "id"); 
    } 

    @Test 
    @ExpectedDatabase(value="/expected_data.xml", assertionMode=DatabaseAssertionMode.NON_STRICT) 
    public void test1() throws Exception{ 
     //run your test logic 
    } 

    @Test 
    @ExpectedDatabase(value="/expected_data.xml", assertionMode=DatabaseAssertionMode.NON_STRICT) 
    public void test2() throws Exception{ 
     //run your test logic 
    } 
} 

그리고 내 예상 데이터 세트는 일부 교체 emp1 및 emp2

필요
<?xml version='1.0' encoding='UTF-8'?> 
<dataset> 

    <company.entity_group ID="15155" corporate_name="comp1"/> 
    <company.entity_group ID="15156" corporate_name="comp2"/> 
    <company.entity_group ID="[emp1]" corporate_name="comp3"/> 
    <company.entity_group ID="[emp2]" corporate_name="comp3"/> 
    <company.ref_entity ID="1" entity_group_id="[emp1]"/> 
    <company.ref_entity ID="2" entity_group_id="[emp2]"/> 

</dataset>