I'm using the fetch API and nock to mock a post request. The test looks like so:
it('should handle the triple bracket replacements ', async () => {
nock('https://jives.dev')
.post('/', {
bestCat: 'cat'
})
.reply(200, {
data: '12345'
})
const data = await retrieveData({
endpoint: 'https://jives.dev/',
configuration: JSON.stringify({
method: 'POST',
body: {
bestCat: 'cat'
}
}),
auth: {cat: 'cat'}
})
expect(data).toEqual({data: '12345'})
})
The retrieveData function runs fetch, and simply maps the endpoint and configuration args into a request as following:
fetch('https://jives.dev/', {
method: 'POST',
body: {
bestCat: 'cat'
}
})
I end up getting an error as if nock is not mocking the request. I can get it to work for get requests but I'm unsure why this isn't working in this example. The error message looks like it's trying to actually make the post request instead of returning data from nock.
- Expected - 3
+ Received + 1
- Object {
- "data": "12345",
- }
+ [Error]
This was caused by me not cleaning all of the mocks in the jest suite. The following resolved this.
afterEach(nock.cleanAll)
afterAll(nock.restore)
Related
I have a service consumer pact test that I am writing, and it seems that when an API call is made it will remove the base url from the request path.
For context, here is the test I am attempting to run.
import { pactWith } from 'jest-pact';
import { Matchers } from '#pact-foundation/pact';
import { ProviderApi } from 'provider-app-api';
import fetch from 'node-fetch';
globalThis.fetch = fetch;
pactWith(
{ consumer: 'ConsumerApp', provider: 'ProviderApp', port: 1234 },
(provider) => {
let providerApi;
beforeEach(() => {
providerApi = new ProviderApi(
provider.mockService.baseUrl,
'access_token'
);
});
describe('ProviderApp API', () => {
beforeEach(() => {
return provider.addInteraction({
state: 'A get request to /segments/{segment_code}/makes',
uponReceiving: 'Some makes exist with segment code vehicles',
withRequest: {
method: 'GET',
path: `${provider.mockService.baseUrl}/segments/vehicles/makes`,
headers: { Authorization: 'Bearer access_token' },
},
willRespondWith: {
status: 200,
headers: { 'Content-Type': 'application/json; charset=utf8' },
body: Matchers.like({
id: 1,
code: 'TOYO',
description: 'Toyota',
start_year: 2011,
end_year: 2021,
segment_code: 'vehicles',
}),
},
});
});
it('returns a successful body', () => {
return vehiclelinkApi.fetchMakes('vehicles').then((response) => {
// assertions to go here
expect(true).toBeTruthy();
});
});
});
}
);
Upon running the test, I get this output:
$ yarn run test:consumer_pact
console.error
at node_modules/#pact-foundation/src/httpPact.ts:121:17
console.error
Pact verification failed!
at node_modules/#pact-foundation/src/httpPact.ts:122:17
console.error
Actual interactions do not match expected interactions for mock MockService.
Missing requests:
GET http://127.0.0.1:1234/segments/vehicles/makes
Unexpected requests:
GET /segments/vehicles/makes
See /home/stefan/project/pact/logs/ConsumerApp-ProviderApp-mockserver-interaction-port-1234.log for details.
It would seem that it's remving the base URL from the fetch call, so the pact server never receives the request, which makes sense. How do I force this to be appended in the call when I use the ProviderAPI? I've ensured that I'm passing provider.mockService.baseUrl in the request, and I've ensured that the value is localhost:1234. Is this an issue that would need to be resolved inside of the ProviderApi package?
That baseUrl shouldn't be in the path property, which should just take the path, not the full URI
I.e. it should just be this
path: "/segments/vehicles/makes",
I'm trying to code a json rpc from scratch. I tried using a fetch, but what the server returns is not the information I want. I believe I need to stay connected waiting for a return from the server. My purpose is to make a request to ganache and get a response. From the ganache log I see that he received the request, but I don't know how to get his return. My initial code was as follows.
const nodeFetch = require('node-fetch')
async function run() {
const retorno = await nodeFetch('HTTP://127.0.0.1:7545', {
method: 'POST',
body: JSON.stringify({
"jsonrpc": "2.0",
"method": "eth_accounts",
"params": [],
"id": 1
}),
headers: {
'Content-Type':'application/json'
}
})
console.log(retorno)}
run();
The answer I get is
Thx
I'm struggling with AXIOS: it seems that my post request is not using my Cookie.
First of all, I'm creating an Axios Instance as following:
const api = axios.create({
baseURL: 'http://mylocalserver:myport/api/',
header: {
'Content-type' : 'application/json',
},
withCredentials: true,
responseType: 'json'
});
The API I'm trying to interact with is requiring a password, thus I'm defining a variable containing my password:
const password = 'mybeautifulpassword';
First, I need to post a request to create a session, and get the cookie:
const createSession = async() => {
const response = await api.post('session', { password: password});
return response.headers['set-cookie'];
}
Now, by using the returned cookie (stored in cookieAuth variable), I can interact with the API.
I know there is an endpoint allowing me to retrieve informations:
const readInfo = async(cookieAuth) => {
return await api.get('endpoint/a', {
headers: {
Cookie: cookieAuth,
}
})
}
This is working properly.
It's another story when I want to launch a post request.
const createInfo = async(cookieAuth, infoName) => {
try {
const data = JSON.stringify({
name: infoName
})
return await api.post('endpoint/a', {
headers: {
Cookie: cookieAuth,
},
data: data,
})
} catch (error) {
console.log(error);
}
};
When I launch the createInfo method, I got a 401 status (Unauthorized). It looks like Axios is not using my cookieAuth for the post request...
If I'm using Postman to make the same request, it works...
What am I doing wrong in this code? Thanks a lot for your help
I finally found my mistake.
As written in the Axios Doc ( https://axios-http.com/docs/instance )
The specified config will be merged with the instance config.
after creating the instance, I must follow the following structure to perform a post requests:
axios#post(url[, data[, config]])
My requests is working now :
await api.post('endpoint/a', {data: data}, {
headers: {
'Cookie': cookiesAuth
}
});
i'm gonna test REST API using Cypress.io , but using chaining request, it wants to be work like this, JSON response body on the first API will be used on the next API Headers for Authorization
I'm already try doing by using cypress commands and printing on console.log, but seems like it does not captured on the log, or is there any clue for this, or i just using another command like cy.route ?
Cypress.Commands.add("session", () => {
return cy.request({
method: 'POST',
url: '/auth/',
headers: {
'Content-Type': 'application/json',
},
body: {
"client_secret" : ""+config.clientSecret_staging,
"username": ""+config.email_staging,
"password": ""+config.password_staging
}
}).then(response => {
const target = (response.body)
})
})
it('GET /capture', () => {
cy.session().then(abc =>{
cy.request({
method: 'GET',
url: '/capture/'+target
})
})
})
the goal is to capture parse of JSON array from target = (response.body)
You have two options:
leave the code as is, be aware that the
.then(response => {
const target = (response.body)
})
code isn't returning anything so the cy.session().then(abc =>{ ... code is getting the whole response (abc is the response of the first .then)
change the code into
.then(response => {
const target = (response.body)
return target // I added this return
})
and then your abc param will be equal to response.body and not to response
That's because if you don't return a subject from your chainable calls the default one will be passed to the next .then function.
Let me know if it satisfies your issue.
p.s. Welcome 👋
I am trying to use Nock. It is matching the URL as per my mock definition.
Though the problem is that my actual request is failing. And I am not being able to test for my response that I am setting up using Nock.
My nock definition looks like so:
nock(process.env.BASE_URL)
.post("/v1.0/api/item", JSON.stringify({"key": "S123"}))
.reply(200, "K123")
.log((data) => console.log(data));
request.post({
headers: headers,
url: process.env.BASE_URL + '/' + url,
body: JSON.stringify(body)
}, function (error, response) {
if ( error ) {
...
}
}
It's entering the error block. Is this expected?
I found the solution to my issue. I realised that I have to provide the expected response json to .reply() to nock.