Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
783 views
in Technique[技术] by (71.8m points)

mocking - Karate mock - how to match against request body content

With Karate, I'm trying to work out how to return different mock responses based on the content of the request body.

I've got

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

When I send a request with either the "gooduser" or "baduser" details, they're falling through to the default scenario. This prints the request, which looks like I'd expect.

For example, if I run

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

I can see in the Karate logs that the first 2 scenarios are being skipped and the match is on (empty). However, the logs are also printing out the request body which looks correct, so I'm surprised the 2nd scenario isn't matching the request I'm sending.

Also, if I remove the '&& request = {...}' clause from the scenario, the match works fine.

Feels like I'm missing something obvious - can anyone please point me in the right direction?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Yes, the == sign won't work for complex objects (in any language), which is why the match syntax of Karate is such a big deal. Keep in mind that the Scenario expression is evaluated as pure JavaScript.

EDIT: for you the simplest option, is to just use the request object directly. Since it is JSON in your case, a simple JS expression like request.username == 'gooduser' will work !

For those who use XML, there are some Karate functions that will do what you need. bodyPath() is what will also work for you. And it is better to make the decision based on one or two values in the payload, not the whole thing, and this is what real servers do anyways:

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

You can use karate.match(request, json) also, but it won't be as elegant.

And as I initially mentioned in the comment, you could move the logic of deciding what to respond with into the body of the Scenario, something like this:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...