Java 春朱松+;莫基托+;内存数据库(H2)

Java 春朱松+;莫基托+;内存数据库(H2),java,unit-testing,mocking,mockito,h2,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(Crea

我目前正在使用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;
    }

...
}
当我运行测试时,结果是0。 mockroadao似乎没有初始化

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;
}
...
}
你能帮我吗:)

先谢谢你

编辑: @巴斯基:当我删除@Mock并改用ReflectionUtils时,mockRoadao的构造函数被调用。但是,当我运行测试时,Mockito并没有模拟方法roadsDao.getRoadsByCEAndDeliveryDate(),该方法实际上被调用,不幸的是,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);
}
}
公共级道路服务测试{
@注射模拟
私人道路服务道路服务;
私人摩克洛道道道道;
@课前
公共静态void setUpClass()引发异常{
}
@以前
public void setUp()引发异常{
initMocks(this);
roadsDao=新mockroadao();
反射测试设置字段(道路服务,“道路SDAO”,道路SDAO);
}
@试验
公共道路({
CreateRoadCriteria=新建CreateRoadCriteria();
标准。设置道路代码(“AA”);
标准:setRoadName(“ANAME”);
标准。setCe(“2”);
标准:设置驱动程序(1);
标准:设置车辆(1);
标准。供应商(1);
所需列表=新的ArrayList();
Mockito.when(roadsDao.getRoadsByCEAndDeliveryDate((RoadsCriteria)Mockito.any())。然后返回(预期);
Mockito.when(roadsDao.getNextVal(Mockito.anyString())。然后调用realmethod();
Mockito.when(roadsDao.createNewRoad(criteria)).thenCallRealMethod();
长期结果=道路服务.createRoad(标准);
Assert.assertEquals(5,结果);
}
}

当您实际使用emulator(inmemory db)时,为什么@Mock在DAO上?删除DAO上的@Mock&调用setup方法中的构造函数。我必须模拟一个方法(roadsDao.getRoadsByCEAndDeliveryDate),而不是其他方法,因为我的内存数据库不起作用(sql查询包含“RANK”,内存中的H2数据库不理解…。我看到您正在尝试对存根进行部分模拟。正如我前面所说,在存根DAO上使用@mock不会真正调用您创建的存根。(a) 移除mockroadao上的@mock,并在setUp方法中(b)构造mockroadao,并使用ReflectionUtil在服务类内设置roadsDao。使用sysout或其他机制确认调用了MockRoadao的构造函数。@Baski感谢您的帮助:)我已经编辑了我的帖子来解释我的问题。您需要用“mock”或“spy”来包装MockRoadao的实例。
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;
}
...
}
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);
}
}