代码之家  ›  专栏  ›  技术社区  ›  Ori Marko

单元测试如何在spring中插入记录(无删除方法)

  •  0
  • Ori Marko  · 技术社区  · 6 年前

    我有用弹簧的刀 jdbcTemplate 使用create read update(no delete)操作。

    create方法的id参数是表中唯一的键。

    除了模拟dao之外,我如何在不违反约束的情况下测试create?

    使用随机id有时仍然会失败

    我应该重写setautocommit以避免添加记录吗?是否仍然认为是有效的单元测试?

    我必须事先在sql中删除数据库中的记录,或者对于这种类型的测试有spring选项吗?

    还是应该把它看作集成测试而不是单元测试?

    编辑

    我在使用oracle,我不能使用sequence为id创建值

    我们在生产中有一些数据源(不用于测试)。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Mark Bramnik    6 年前

    这实际上取决于这样一个测试的目的是什么,并不是所有的测试都是“单元测试”。

    例如,如果目标是测试封装业务逻辑的“服务”,但是从这个服务中,有时会调用dao,那么最好的方法可能就是按照您的建议模拟dao。 在这种情况下,dao显然不会被这个测试覆盖,但是服务会被覆盖。

    如果目的是测试sql语句(我假设dao只包含sql语句+可能将它们转换为域对象),那么mocking不是一个选项。

    在这种情况下,测试应该包括对某种数据库的调用,但在这种情况下,它不再被称为单元测试(单元测试是一种运行速度非常快且只在内存中运行的测试,没有dbs、i/o等)。我将此称为集成测试(正如您所建议的那样),但不同的人对此类测试可能有不同的名称。

    实际上,我们需要两种测试,因为它们测试不同的东西

    那么,如何测试这个呢?

    首先要决定使用哪一个数据库,这里有三种方法:

    1. 运行一个真实的数据库,在用户之间共享,测试假设它是预先安装的
    2. 使用内存数据库运行
    3. 运行测试套件时运行数据库的db docker映像,然后销毁它

    虽然对哪种方法更好的讨论本身就很有趣,但它超出了海事组织这个问题的范围,每个选择都有其影响。

    一旦您完成了这个决定,您应该决定如何从代码中使用这个数据库。

    通常,弹簧测试使用以下模式:

    1. 在测试前打开事务
    2. 运行测试(如果需要,可以更改数据,甚至更改模式-添加列、表)。做断言
    3. 不管测试结果如何,回滚事务,以便数据与测试之前的数据相同

    因此,如果对所有测试都采用这种方法,那么它们将以“空”数据状态开始,这样就不会出现约束冲突 这也有效地解决了“删除记录”的问题,因为当事务回滚时,数据无论如何都会被删除。

    现在是关于删除事务之外的记录。

    一个明显的方法是从测试中执行一个删除SQL(在DAO之外),这样DAO(生产代码就不会被更改)

    您可以将datasource/jdbctemplate直接插入到测试中(spring测试完全支持这一点),并从中调用所需的sql