在java中测试数据库类

时间:2017-05-10 18:20:07

标签: java unit-testing junit mockito powermock

我有一个类来执行基本的数据库操作,例如DB中的保存,检索和删除对象。它有一个saveObject方法,在每次操作之前调用它。

我还有另一个类,它调用DB类中的java.lang.ExceptionInInitializerError方法来存储它创建的图形,如果它在getter中返回之前不存在。为了测试这个getter,我尝试了junit,但它在存储对象的部分失败,并在我第一次设置图形时给我java.lang.NoClassDefFoundError然后尝试检索它但是当我调用getter而没有先设置图形时这样就会创建图表,然后我得到一个public final class DbUtils { private static Connection connectionDB; private static void establishConnection() { ... } private static void closeConnection() { ... } public static void saveObject(final Object graph, final Object map) { establishConnection(); //convert Objects to Byte and store it; closeConnection(); } public static Map<String, Object> retrieveObject(final String key) { establishConnection(); //read byte and convert to object closeConnection(); return multireturn; } public static boolean deleteObject(final String key) { establishConnection(); //delete all object except object with key closeConnection(); return (affectedRow >= 1); } } 。我需要使用单元测试来测试这两个类,但我无法找到任何简单的示例。

DB class outline:

public class GraphCreation {
    Graph graph;
    ...
    private createGraph(){....}

    public void setGraph(Graph G){
        this.graph=G;
    }

    public Graph getGraph(){
        if(this.graph==null){
            createGraph();
        }
        saveToDB(graph, map);
        return this.graph
    }

}

GraphCreation类:

@Mock
GraphCreation graph;

@Test
public void testSettingDependencyGraph() {
    graphCreation.setGraph(graph);
    Assert.assertEquals(Graph, graphCreation.getGraph());
}

@Test
public void testCreatingGraph(){
    graphCreation.setApplicationContext(applicationContext);
    graphCreation.setGraph(new Graph());
    moduleRegistrationBeans = new HashMap<String, ModuleRegistration>();
    ModuleRegistration m1 = new ModuleRegistration();
    m1.setName("module1");
    SDF1 = new TestSourceDataFactoryTemplate();
    VM1 = new TestModuleTemplate();
    m1.setSourceDataFactory(SDF1);
    m1.setModule(VM1);
    moduleRegistrationBeans.put("module_1", m1);
    PowerMock.reset(BeanFactoryUtils.class);
    PowerMock.mockStatic(BeanFactoryUtils.class);
    EasyMock.expect(BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleRegistration.class)).andReturn(moduleRegistrationBeans);
    PowerMock.replay(BeanFactoryUtils.class);
    graphCreation.getDependencyGraph();
}

当前测试:

 let pointA = [-70, 43]
 let pointB = [-83, 32]

两个测试都在GraphCreation类的saveToDB()方法中失败。 我是单元测试的新手,这些测试是由其他开发人员编写的,我添加了数据库功能,现在单元测试失败了。 有人可以帮助我或指导我如何解决这个问题并为数据库类创建单元测试。

1 个答案:

答案 0 :(得分:1)

看起来你自己负担过重;或者反过来说:你试着做很多事情......没有太多想法你在做什么。

首先:DbUtils静态方法。这是一个“直接”的任务,但有一些微妙的事情要做对。如果你陷入困境,那根本就行不通。因此:您必须完全遵循所列的所有步骤here

但更重要的是:你不明白嘲笑本质上是什么。含义 - 这里:

@Mock
GraphCreation graph;

一起
graphCreation.setApplicationContext(applicationContext);
graphCreation.setGraph(new Graph());
...

根本不会使任何感觉。

当您告诉Mockito(或PowerMock或任何其他框架)模拟类时,您可以创建模拟。那个模拟只是“看起来”属于被测试的那个阶级;但它只不过是一个“空壳”。该对象与您的生产代码无法相关。换句话说:像你一样调用该模拟对象上的方法是 no op 。这没有实现任何有用的东西!

相反:您使用new实例化类的对象!也许你为那个“真实”对象提供模拟对象;因为真实对象需要单元测试环境中那些被模拟的东西。然后你在真实对象上调用一个方法;并且你对结果“断言”;或者你可以验证提供给真实对象的模拟看到了你期望看到的方法调用。

长话短说:退一步,阅读如何正确进行单元测试,以及如何在那里发挥模拟作用。开始阅读here

除此之外:在整个地方使用静态方法是不良做法。您应该认真考虑用非静态版本替换该解决方案(或者至少:在静态类周围放置一个包装器)。因为那样你也可以在没有 PowerMock的情况下进行测试。

最后:NoClassDefFoundError表示您正在尝试运行某些内容......但是类路径设置中缺少一个/多个必需的类。可能是因为你的嘲弄错了。

但重点是:减速;并且了解您想要做什么。而不是构建一个巨大的,复杂的问题,实际上包含许多关于你正在做的事情的微妙的不知情。