In Karate API mocking not working as expected for me
I am exploring Karate API double (mocking) for the integration test. For the below scenarios, I'm not getting the expected mocking response. Your help will be appreciated.
My Setup : 1. Karate Mock Server up with pathMatches rules on port 8001: http://localhost:8001 ( working, validated against "/cat" and some test calls) 2. My own Application is up from docker on port 8080. From Docker exposed 8001 port as well.
Mocking Case: 1. My application REST call exposed to all users http://localhost:8080/service/v1/findUser. This exposed API, underlying calling other REST call http://dev-STG/userservice/v1/findUser which actually giving JSON response. So, I want to mock underlying API call and validate my API behavior accordingly.
Steps tried: 1. Now, in my application config, m replacing actual underlying API call to Karate mock server(http://localhost:8001/userservice/v1/findUser). Then did build & up my application docker.
- In Karate, I defined test e.g "testIntgrtn.feature" which calling my application API "http://localhost:8080/service/v1/findUser" and Karate mock server up and set with pathmatch "/userservice/v1/findUser".
- After executing "testIntgrtn.feature" karate not mocking for an underlying call(http://localhost:8001/userservice/v1/findUser).
-
Now, in "testIntgrtn.feature" file I changed my-application URL to underlying REST URL i.e (http://localhost:8001/userservice/v1/findUser) then mocking will work like charm.
I'm not understanding why underlying API call not getting mocked here? Did I miss something here? Also, in Karate can we monitor all REST calls (like cypress mocking).
Thanks for this wonderful framework. Which is intuitive for writing automation cases.
Solution 1:
Karate cannot automatically intercept calls.
The recommended approach is when you boot the application running at localhost:8080
you change the configuration so that instead of calling http://dev-stg/userservice/v1/findUser
it calls something like http://localhost:8001/v1/findUser
. This is what most teams do, and is easy because you should anyway be defining external URL-s as application.properties
(or equivalent) as a best-practice.
It is very easy to over-ride an application property in Spring Boot for example, you can do this via the command-line: https://stackoverflow.com/a/37053004/143475
If you want, you can dynamically provision a port for the mock. So your unit test can first start a mock, get the port, and then start the server. You can find details in the Karate documentation.
All this said, if you are able to change the (system) HTTP proxy before the app at localhost:8080
starts, you may be able to do this without modifying the configuration. (But it is tricky, so I recommend the approach explained above.) So in this case, Karate can actually "intercept" the outgoing HTTP calls that the app at localhost:8080
makes.
See the second-last row (5a) in the table here: https://github.com/intuit/karate/tree/master/karate-netty#consumer-provider-example