1

我正在尝试对我的课程进行单元测试,并模拟 DAO 以提供可预测的结果。尽管如此,当我收到休眠错误时,似乎仍在调用我的 DAO 方法。

org.hibernate.exception.GenericJDBCException:找不到站 TST。

这个错误是我的数据库不包含 TST 的结果,但是因为我模拟了 DAO,所以不应该调用它吗?我如何模拟调用,以便甚至不命中数据库。

这是我设置模拟的方式

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
public class MyServiceTest{

    @Autowired
    private MyService service;

    private MyDAO dao;

    private LinkedList objs;    


    @Before
    public void init() throws SecurityException, NoSuchFieldException,
            IllegalArgumentException, IllegalAccessException {


        // mock the dao for predictable results
        dao = mock(MyDAO.class);

        when(dao.myDBCall(anyString(), any(Date.class))).thenReturn(legs);
        Field f = MyService.class.getDeclaredField("dao");
        f.setAccessible(true);
        f.set(service, dao);


    }

    @Test
    public void testCall() {
        // construct our sample leg data
        legs = new LinkedList();
//fill in my stub data i want to return

        Collections.shuffle(legs);

        List results = service.testingCall("TST", new Date()); // this fails because service is using the dao, but it is making a call to the DB with this garbage 'Test' param rather than just returning 'legs' as stated in my when clause
        assertThat(results, not(nullValue()));


    }

    @Test
    public void testGetGates() {
        // fail("Not yet implemented");
    }

    @Test
    public void testGetStations() {
        // fail("Not yet implemented");
    }
}
4

2 回答 2

2

我认为你Service是由 spring 实例化的,并且Daoapplication-context.xml你尝试将你的模拟注入你的服务之前你就得到了错误。

我喜欢用来测试我的服务的一件事是Autowired构造函数,然后在我的测试中,我没有通过 spring 实例化我的服务,而是使用构造函数和模拟。

private MyDao myDao;

@Autowired
public MyService(MyDao myDao){
this.myDao = myDao;
}

然后在你的测试中:

MyService myService = new Myservice(mockedDao);
于 2013-03-13T22:19:06.747 回答
1

首先,而不是Field f = MyService.class.getDeclaredField("dao");检查PowerMock(检查Whitebox

模拟一个对象不会阻止休眠启动(因为您正在加载applicationContext.xml,所以休眠将尝试连接到数据库)。您的模拟 - 它只是一个测试实例的一个字段的 POJO,而不是 Spring bean 或类的替代品。

如果您只想测试 dao 和服务类(创建清晰的单元测试) - 从测试中删除与 Spring 相关的注释并自己进行(创建模拟,创建服务,将模拟放入服务并测试它)。

如果您想使用 Spring 上下文(创建集成测试)测试您的应用程序 - 为休眠创建H2 内存数据库并测试您的服务(不要忘记在 中清除它@After)。

第三种方式 - 将您的配置文件拆分为两个 Spring 配置文件(例如devtest)并自己实现模拟(将模拟放到test、真正的休眠和 dao 到dev)。

如果您不想使用 Spring 配置文件 - 可以拆分applicationContext.xml为 3 个文件(用于普通 bean,用于真正的 DB bean,用于模拟)。

还有一种更性感的方式——使用springockito-annotations(但你仍然需要避免加载 hibernate)

于 2013-03-13T22:26:25.480 回答