嘲笑node.js中的数据库?
如何在我的node.js应用程序中模拟出数据库,在这种情况下,使用mongodb
作为博客REST API的后端?
当然,我可以将数据库设置为特定的testing
数据库,但是我仍然可以保存数据,而不是只testing我的代码,而且还testing数据库,所以实际上我并没有进行unit testing,而是进行了集成testing。
那么应该怎么做? 创build数据库包装作为应用程序和数据库之间的中间层,并在testing中replaceDAL?
// app.js var express = require('express'); app = express(), mongo = require('mongoskin'), db = mongo.db('localhost:27017/test?auto_reconnect'); app.get('/posts/:slug', function(req, res){ db.collection('posts').findOne({slug: req.params.slug}, function (err, post) { res.send(JSON.stringify(post), 200); }); }); app.listen(3000);
// test.js r = require('requestah')(3000); describe("Does some testing", function() { it("Fetches a blogpost by slug", function(done) { r.get("/posts/aslug", function(res) { expect(res.statusCode).to.equal(200); expect(JSON.parse(res.body)["title"]).to.not.equal(null); return done(); }); }); ));
我不认为数据库相关的代码可以正确地testing,而不用数据库软件进行testing。 那是因为你正在testing的代码不仅仅是javascript而且是数据库查询string。 即使在你的情况下查询看起来很简单,你不能依靠它永远那样。
所以任何数据库仿真层都必须实现整个数据库(可能还没有磁盘存储)。 那么,即使您称之为unit testing,您最终也将使用数据库仿真器进行集成testing。 另一个缺点是数据库模拟器可能最终会产生与数据库不同的一组错误,并且最终可能不得不为数据库模拟器和数据库编写代码(类似于IE,Firefox和Chrome等的情况)。 )。
因此,在我看来,正确testing代码的唯一方法就是将其与真实数据库连接起来。
有一个一般的经验法则,当涉及到嘲笑这是
不要嘲笑你不拥有的东西。
如果你想嘲笑数据库隐藏它抛出一个抽象的服务层,并嘲笑该层。 然后确保你集成testing实际的服务层。
就我个人而言,我已经不再使用mock进行testing,而是使用它们进行自上而下的devise,帮助我从顶部到底部推动开发,汲取服务层,然后最终实现这些层并编写集成testing。 作为testing工具,他们倾向于使你的testing非常脆弱,在最坏的情况下导致实际行为和嘲弄行为之间的分歧。
到目前为止,我不同意所选答案或其他答复。
如果你能够捕捉由混沌产生的错误,以及在获得质量保证之前对DB模式和代码进行了多次混乱的改变,这难道不是真棒吗? 我敢打赌,大多数人会大声呐喊!
你当然可以,应该隔离和testing你的DB模式。 而不是基于模拟器或重型图像或DB和机器的娱乐。 就像SQLite这样的东西就是一个例子。 你可以根据内存中的轻量级实例来运行它,并且在内存实例中不会改变静态数据,这意味着你真正在testing你的数据库,你也可以相信你的testing。 显然这很快,因为它在内存中,是一个骨架,并在testing运行结束时被废弃。
所以是的,你应该和你应该testing导出到一个非常轻量级的内存实例中的任何数据库引擎/运行时使用的SCHEMA,并添加一个非常less量的静态数据成为你孤立的模拟数据库。
您可以定期(以自动方式)从实际DB中导出实际模式,并在每次推送QA之前将其导入/更新到内存数据库实例中,然后您将立即知道数据库pipe理员或其他人最近改变了模式的开发者打破了任何testing。
虽然我赞扬努力尽力回答,但如果可以的话,我会低估当前的答案,但是我是新的,并没有build立起足够的声望,还没有使我能够这样做。
至于那个回答“不要嘲笑你不拥有的东西”的人。 我想他的意思是说“不要testing你不拥有的东西”。 但是你嘲笑你不拥有的东西! 因为这些都是未经testing的东西需要被隔离!
我打算和你一起分享这个HOW,并且会在未来的时间里用真实的JS代码更新这个post!
这是许多testing驱动团队一直在做的事情。 你只需要了解如何。
我使用任何语言来testing数据库代码的首选方法是通过存储库抽象访问Mongo(这里有一个例子http://iainjmitchell.com/blog/?p=884 )。 实现将根据数据库特定的function而有所不同,但是通过从您自己的逻辑中删除所有的Mongo代码,您就可以进行unit testing。 简单地用一个残缺的版本来取代Mongo Repository实现,这是非常简单的。 例如,只需将对象存储在简单的内存字典集合中即可。
您将以这种方式testing自己的代码,而不需要数据库依赖关系,但仍然需要对主数据库执行集成testing,因为您可能永远无法模拟真实数据库的特性,在这里说。 我发现的东西类似于安全模式下的索引,而没有安全模式。 具体来说,如果你有一个唯一的索引,你的虚拟内存实现可能会在所有情况下,但是Mongo不会没有安全模式。
因此,虽然您仍然需要针对数据库进行某些操作testing,但您仍然可以使用残缺的存储库实现unit testing自己的逻辑。
什么?! 为什么要嘲笑一切呢? 嘲笑的目的是跳过复杂性和unit testing自己的代码。 如果你想写e2etesting,然后使用数据库。
编写代码来设置/拆卸一个testing数据库用于unit testing是技术债务,令人难以置信的不满意。
在npm中有模拟库:
mongo – https://www.npmjs.com/package/mongomock
mongoose – https://www.npmjs.com/package/mockgoose
如果那些不支持你需要的function,那么是的,你可能需要使用真实的东西。
我有这个困境,select与testing数据库一起工作,并在每次testing开始时清理它。 (如何删除所有内容: https : //stackoverflow.com/a/25639377/378594 )
使用NPM,您甚至可以创build一个testing脚本来创build数据库文件,并在之后进行清理。