2017-09-25 87 views
1

我在节点项目中使用mysql。node.js上的单元测试mysql回滚

我想单元测试一个使sql事务的javascript函数。如果事务成为锁定监视器的受害者,则该函数具有处理失败的代码。

还是呢?

因为我是单元测试,所以我只在一个本地数据库上一次创建一个事务,所以永远不会出现死锁,对吧?我如何测试死锁处理,如果它永远不会发生?有没有办法强制它发生?

例子:

thisMustBeDoneBeforeTheQuery(); 
connection.queryAsync(/*This is an update*/).catch(function(err) { 
    undoThatStuffIDidBeforeTheQuery(); 
    // I hope that function worked, because my unit tests can't 
    // make a deadlock happen, so I can't know for sure. 
} 
+0

你应该嘲笑数据库的东西,并在测试案例假死锁错误。然后你可以测试你的错误代码的有效性。这取决于你的用例。处理持久层的单元测试可能变得非常不安全。这也取决于你的代码如何适合正确的测试策略。 – k0pernikus

+0

相关:https://stackoverflow.com/questions/8389149/how-do-you-mock-mysql-without-an-orm-in-node-js – k0pernikus

+0

它似乎嘲笑SQL可能工作。我会试一试。 –

回答

0

什么是你的测试需要警惕或验证的基本行为?你需要测试你的mysql驱动程序吗?还是MySql本身?我认为@ k0pernikus确定了最高值测试:

假设数据库客户端由于死锁而导致异常,那么应用程序代码如何处理它?

您应该可以非常容易地使用模拟库或依赖注入来创建测试工具,并测试存根来模拟客户端驱动程序返回死锁异常。这不应该需要与mysql进行任何交互,除了初始调查之外,请查看mysql客户端驱动程序的返回代码/错误异常传播的外观。

这不是一个100%完美的测试,并且在mysql客户端库更改的情况下仍然会使您容易受到攻击。


由于时间原因,确定性地重现并发问题通常是非常困难的。但使用SELECT ... FOR UPDATE和多个事务应该能够确定性地重现mysql上的死锁,以验证您的客户端库代码。