Spring JUnit + Mockito +内存数据库(H2)

时间:2017-04-06 13:59:57

标签: java unit-testing mocking mockito h2

我目前正在使用Mockito和内存数据库(H2)来测试某些服务和dao。

我试图测试我的服务的方法(createRoad),其中包含一些dao方法的调用:

@Service(value = "RoadsService")
public class RoadsService implements IRoadsService {

@Autowired
private IRoadsDao roadsDao;

...

@Override
public long createRoad(CreateRoadCriteria criteria) {
    String roaCodeToCopy = "";
    RoadsCriteria roadsCriteria = new RoadsCriteria();
    roadsCriteria.setCe(criteria.getCe());
    roadsCriteria.setDeliveryDate(new Date());
    List<WebRoadsModel> listRoadsCe = roadsDao
            .getRoadsByCEAndDeliveryDate(roadsCriteria);
    for (WebRoadsModel wrm : listRoadsCe) {
        if (wrm.getRoaCode().endsWith("90")) {
            roaCodeToCopy = wrm.getRoaCode();
            break;
        }
    }
    criteria.setRoadCode(StringUtils.substring(roaCodeToCopy, 0, 4)
            + criteria.getRoadCode());
    // 2. Creation of the new road
    long idNewRoad = roadsDao.createNewRoad(criteria);

    if (!"".equals(roaCodeToCopy) && listRoadsCe.get(0) != null) {
        roaCodeToCopy = listRoadsCe.get(0).getRoaCode();
        // 3. Copy dates closed of this trn
        RoadsCriteria newRoadCreated = new RoadsCriteria();
        newRoadCreated.setCe(criteria.getCe());
        newRoadCreated.setRoadId(idNewRoad);
        // 4. Paste it for the new road
        deliveryCalendarDao.copyClosedDates(roadsDao
                .getRoadByCriteria(newRoadCreated).get(0).getRoaCode(),
                roaCodeToCopy);
    }

    return idNewRoad;
    }

...
}

我需要模拟名为 getRoadsByCEAndDeliveryDate 的方法,因为后面的sql查询不是由H2驱动程序管理的(使用&#34; RANK&#34;查询)。然后,我想在此服务中使用H2和其他方法。

我试过这个:

public class RoadsServiceTest {

@InjectMocks
private RoadsService roadsService;

@Mock
private MockRoadDao roadsDao;

@BeforeClass
public static void setUpClass() throws Exception {

}

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
}

@Test
public void createRoad(){
    CreateRoadCriteria criteria = new CreateRoadCriteria();
    criteria.setRoadCode("AA");
    criteria.setRoadName("ANAME");
    criteria.setCe("2");
    criteria.setDriver(1);
    criteria.setVehicle(1);
    criteria.setSupplier(1);

    List<WebRoadsModel> expected = new ArrayList<WebRoadsModel>();
    Mockito.when(roadsDao.getRoadsByCEAndDeliveryDate((RoadsCriteria) Mockito.any())).thenReturn(expected);
    Mockito.when(roadsDao.getNextVal(Mockito.anyString())).thenCallRealMethod();
    Mockito.when(roadsDao.createNewRoad(criteria)).thenCallRealMethod();

    long result = roadsService.createRoad(criteria);
    Assert.assertEquals(5, result);
}
}

除了assertEquals之外几乎是好的。 根据我在内存数据库中使用的sql文件,我有一个像这样的sql序列:

CREATE SEQUENCE  "SEQ_SITI_ROADS"  MINVALUE 1 MAXVALUE 99999 INCREMENT BY 1 START WITH 5 CACHE 20 ;

当我运行测试时,结果为0。 似乎MockRoadDao没有初始化。

public class MockRoadDao extends RoadsDao {

public MockRoadDao() throws DatabaseUnitException, SQLException, MalformedURLException {
    IDataSet dataSet = new FlatXmlDataSetBuilder().build(new File("./src/test/resources/dataset.xml"));

    DataSource dataSource = TestUtils.dataSource();

    IDatabaseConnection dbConn = new DatabaseDataSourceConnection(dataSource);
    DatabaseOperation.CLEAN_INSERT.execute(dbConn, dataSet);

    User user = new User();
    user.setLangCountry("ENFR");
    BackendContextHolder.setBackendIdentifier(new BackendIdentifierImpl(user));
    final NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
    setJdbcTemplate(jdbcTemplate);
}

}

public class TestUtils {

private static final Logger LOG = LoggerFactory.getLogger(TestUtils.class);

public static DataSource datasource;

/**
 * @return
 */
public static DataSource dataSource() {
    if (datasource == null) {

        EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
        EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.H2).addScript("classpath:/siti-create.sql").build();
        datasource = db;
    }
    return datasource;
}
...
}

你能帮帮我吗:)

提前谢谢

修改: @Baski:当我删除@Mock并使用ReflectionUtils时,会调用MockRoadDAO的构造函数。但是,当我运行测试时,方法 roadsDao.getRoadsByCEAndDeliveryDate()没有被Mockito模拟,该方法确实被调用,不幸的是,SQL查询不是由H2驱动程序管理的。

public class RoadsServiceTest {

@InjectMocks
private RoadsService roadsService;

private MockRoadDao roadsDao;

@BeforeClass
public static void setUpClass() throws Exception {

}

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
    roadsDao = new MockRoadDao();
    ReflectionTestUtils.setField(roadsService, "roadsDao", roadsDao);
}

@Test
public void createRoad(){
    CreateRoadCriteria criteria = new CreateRoadCriteria();
    criteria.setRoadCode("AA");
    criteria.setRoadName("ANAME");
    criteria.setCe("2");
    criteria.setDriver(1);
    criteria.setVehicle(1);
    criteria.setSupplier(1);

    List<WebRoadsModel> expected = new ArrayList<WebRoadsModel>();
    Mockito.when(roadsDao.getRoadsByCEAndDeliveryDate((RoadsCriteria) Mockito.any())).thenReturn(expected);
    Mockito.when(roadsDao.getNextVal(Mockito.anyString())).thenCallRealMethod();
    Mockito.when(roadsDao.createNewRoad(criteria)).thenCallRealMethod();

    long result = roadsService.createRoad(criteria);
    Assert.assertEquals(5, result);
}
}

0 个答案:

没有答案