ut PL SQL 测试存储过程

Ut PL SQL to test stored procedure

我是 UT PLSQL 的新手。我们有一个包含大量存储过程的现有应用程序。最后的大多数过程将值插入或更新到 tables。 utplsql 中有什么方法可以测试这些 table 值吗?我可以看到很多关于函数的例子,而不是存储过程。

谢谢

测试数据

在单元测试中,您可以测试的不仅仅是功能结果。执行存储过程后,您可以查询 table 并查看它是否插入了您期望插入的内容。

根据存储过程的不同,可能很难准确找到它插入了哪些数据,但在许多情况下,您可以做到这一点,因为您可以搜索特定值,使用序列来获取插入的 ID,等等。

为了将数据与您的期望进行比较,您 select 将数据放入变量中并将其与期望值进行比较(如果您需要比较多行,则可以在游标循环中执行此操作),但它可能更容易比较两个游标,一个具有预期数据(您可以使用 select from dual 构造它),另一个具有实际数据。

文档,尤其是 Advanced data comparison 章,包含有关如何比较游标数据的各种示例。我不会在这里粘贴它们,因为我不知道哪一个适用于你的情况,而且 utPLSQL 及其文档都非常活跃,因此,最好在需要时查看最新版本。

将您的过程重构为一个包

然而,您可能会发现很难通过输出的数据来测试大型、复杂的存储过程。我发现重构它的最简单方法是创建一个包。在包中,您可以像现在一样公开一个过程,但它可以调用包中的其他过程和函数,您也可以公开这些过程和函数。这样,测试那些单独的部分就更容易了,也许你可以在不需要写入数据的情况下测试大部分逻辑,从而使测试更容易编写并且执行起来更快。

这并不完全优雅,因为您只是为了测试目的而暴露了您不会暴露的部分。尽管如此,我发现将存储过程重构到包中通常非常容易,特别是如果您已经在存储过程中使用了子过程,这样您就可以快速且没有太大风险地获得易于测试的结构.

它不必在包中,你也可以将它拆分成更小的过程,但我喜欢包,因为它们将存储过程的所有逻辑放在一起,它允许你调用proc 的方式与之前大致相同。包只不过是一组分组的存储过程、函数和类型。如果您的应用程序需要它,您甚至可以保留原始存储过程,但让它在包中调用它的对应部分,这样您就可以进行重构而无需更改任何客户端。

将部分过程重构为对象类型

如果再进一步,你可以制作对象类型。这有很多优点,但它们的工作方式与包有很大不同,所以如果您不熟悉它们,这可能是一大步。

  • 首先,对象可以保持一个状态,如果需要,您可以拥有多个状态。包也可以保存状态,但每个会话或每次调用数据库只能保存一个状态。对象类型允许您根据需要创建任意数量的实例,并且每个实例都保持自己的状态。
  • 对于对象类型,您拥有可以传递的对象实例。这意味着您可以通过将某种类型的对象传递给存储过程,将一些逻辑注入到存储过程中。此外,您可以创建对象的子类型,因此如果您的过程不会将数据写入 table,而是调用某种类型 X 的方法来进行实际保存,您可以使用类型 Y 的子类型进行测试X,它实际上并不保存数据,只是帮助您验证是否使用正确的参数调用了该方法。然后您将进入 mocking 领域,这是提高测试效率的非常有用的工具。

同样,客户端可能还没有准备好像这样传递对象,所以我倾向于创建两个(或更多)程序包。一个是应用程序的官方入口点。除了创建 X 类型的对象并将其传递给包含实际逻辑(可选择进一步拆分)的第二个过程外,它不会做太多事情。这样,我的应用程序可以调用一个简单的存储过程,而我的测试可以调用第二个存储过程并在需要时将其传递给子类型 Y 的实例。