如何Mock Express的会话

文章翻译自How to Mock an Express session

你是否正在使用Express框架?你是不是正在做服务端的集成测试(end-to-end)?这里我将讨论在项目中遇到的问题。这篇文章涵盖了我在使用Express框架做集成测试时所遇到的挑战,以及我是如何寻找技术解决方案的。

当你也遇到相同的问题时,希望这篇文章对你有所帮助。

背景

我做的项目是先要向amazon s3批量上传图片文件,然后对这些文件做一些裁剪、压缩和编辑的任务。

使用Express中间件做认证、授权以及设置上下文的工作都很顺利。我使用cookie-session作为控制session的中间件,这就意味着需要cookie-session负责相应session数据的加密、配置和解密。

我知道许多开发者使用sinon for unit testing。如果你对它不熟悉,我先简短介绍下它:sinon for unit testing是通过Javascript的测试框架(如mocha)来实现mock的方法。但是问题来了,如果要实现Express Session的mock测试?在Express中有没有实现mock session的解决方案?

Test Expressing.jpeg

挑战

下面我将讲述我所遇到的挑战。我有两个路由,一个是向s3上传图片的、另一个是对上传图片做一些额外处理(如压缩、编辑)。对于第一个路由我先设置请求的session,然后再跳转到第二个路由。

1)api/image/create

exports.create = function(req, res) {
  // upload image to s3
  var photos = PhotosTable.create(req.files.names); // add entries in database
  req.session.count = photos.length; // set count in req.session
  res.redirect(`api/image/submit`);
}
  1. api/image/submit (need to add a test case for this one)
exports.submit = function(req, res) {
  if (req.session.count && req.session.count > 0) { // get count from req.session
    // perform further tasks
    res.sendStatus(200); 
  } else {
    res.sendStatus(400); 
  }
}

我想mock第二个路由(api/image/submit)。然而问题是:(pi/image/submit)这个路由需要先核查req.session.count,然后在继续后面的操作。如果count是空值,回应400。使用Mocha框架你只能mock第一个路由,不能实现下面的功能:第一个路由跳转到第二个路由,然后程序从第二个路由向第一个路由的返回值,然后验证第二个路由返回值的测试用例。

这个问题看起来很简单,但是实现起来遇到很多挑战

最简单的解决方案是在测试用例中,通过req params直接请求第二个路由,然后检查params是否存在,如果存在就取消检查req.session.count。

然而,这种解决方案并不是最好的。因为

  • 这不是一种普通的方式,因此这种方法不能被重用
  • 在代码中添加额外的if/else来控制req.params,就会需要更多的代码来确保原来的逻辑不受影响

我们也可以放弃使用两个个路由,把所有的代码都写在一个路由中。但是我们真的要这么做吗?据我所知,不应该为了测试用例更改代码(one should never change implementatin for the sake of test cases)

这个问题看起来很普通,但是我在网上(至少是在StackOverFlow)上并没有找到解决方案。起初我猜测在一些模块中已经解决了这个问题,诸如mocha, 或是cookie-seeion等经常在Express中使用的模块。

然而,并没有。

我最终是如何解决的

在程序中我是使用cookie-session来维护Express与session间的管理工作。cookie-session通过Keygrip和Crypto来设置和验证session的签名。

在设置session cookies时需要name和key:
name被用来作为cookie的名字。
key是作为Keygrip对cookie值进行签名的概要值。

我在测试用例请求第二个路由时,设置req.session.count的值。下面就是代码:

// name = "my-session" ->  base64 value of required object (cookie)
// name.sig = "my-session.sig" -> signed value of cookie using Keygrip

let cookie = Buffer.from(JSON.stringify({"count":2})).toString('base64'); // base64 converted value of cookie

let kg = Keygrip(['testKey']) // same key as I'm using in my app
let hash = kg.sign('my-session=' + cookie);

await request(app).get('api/image/submit').set("Accept", "text/html")
    .set('cookie', ['my-session=' + cookie + '; ' + 'my-session.sig=' + hash + ';'])
    .expect(200);

这仅仅是一条mock session的测试用例。在大多数情况下,测试用例需要定制所要测试的参数值,但这个代码可以设置任何你想测试的参数。

我已经创建一个Nodejs.js包并发不到npm中,通过这个包mock-session,你可以很容易做mock session的测试。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容