空手道模拟-如何与请求正文内容匹配

时间:2019-08-12 07:42:17

标签: mocking karate

使用空手道,我正在尝试找出如何根据请求正文的内容返回不同的模拟响应。

我有

Feature: ...
Scenario: pathMatches('/users/login') && methodIs('post') && request == {"username": "gooduser", "password": "goodpassword"}
  * def responseStatus = 200
  * def response = {"status: login ok"}
Scenario: pathMatches('/users/login') && methodIs('post') && request == {"username": "baduser", "password": "badpassword"}
  * def responseStatus = 401
  * def response = {"status: login not ok"}
Scenario:
  * print request
  * print requestHeaders

当我发送带有“ gooduser”或“ baduser”详细信息的请求时,它们陷入默认情况。这会打印请求,看起来像我期望的那样。

例如,如果我跑步

curl -X POST -d '{"username":"baduser","password":"badpassword"}' http://localhost:8999/users/login

我在空手道日志中看到,前两个场景已被跳过,比赛进行中(空)。但是,日志还会打印出看起来正确的请求正文,因此令我惊讶的是第二种情况与我发送的请求不匹配。

此外,如果我从方案中删除了“ && request = {...}”子句,则匹配效果很好。

感觉好像我缺少明显的东西-有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:1)

是的,==符号不适用于复杂对象(任何语言),这就是为什么空手道的match语法如此重要的原因。请记住,Scenario表达式被评估为纯JavaScript。

编辑:对您来说,最简单的选择就是直接使用request对象。由于您使用的是JSON,因此像request.username == 'gooduser'这样的简单JS表达式就可以工作!

对于那些使用XML的人来说,有一些空手道函数可以满足您的需求。 bodyPath()也会为您服务。而且最好根据有效负载中的一个或两个值而不是整个事情来做出决定,而这正是 real 服务器所做的:

Scenario: pathMatches('/users/login') && methodIs('post') && bodyPath('$.username') == 'gooduser'

您也可以使用karate.match(request, json),但它不会那么优雅。

正如我最初在评论中提到的那样,您可以将决定如何响应的逻辑转移到Scenario的正文中,如下所示:

* def response = request.username == 'gooduser' ? read('good.json') : read('bad.json')