I'm trying to understand why Jest is not allowing me to import functions from _mocks_/http.js.
This is my catchAnalysis.js file
import { fetchNewsData } from './http'
async function catchAnalysis(params) {
console.log("::: Form Submitted :::")
fetchNewsData(params)
.then(response => /* Blablabla */)
.catch(error => console.log('error', error));
}
This works great. Below is my catchAnalysis.test.js file:
jest.mock('./http')
import { fetchNewsData } from './http'
test("Mock API works", () =>{
let testing = fetchNewsData()
console.log(`fetchNewsData value is ${testing}`)
/* Blablabla */
})
fetchNewsData() is undefined when I run JEST tests with npm.
Am I using jest.mock('') incorrectly? I don't know where to start to debug.
For context, this is the _mocks_/http.js file. The real file is a simple fetch API call.
function fetchNewsData(){
console.log("::: MOCK API :::")
let responseData = {
"agreement": "DISAGREEMENT",
"confidence": "86",
"irony": "NONIRONIC",
"model": "general_en",
"score_tag": "P",
"status": {
"code": "0",
"msg": "OK",
"credits": "3",
"remaining_credits": "19849"
},
"subjectivity": "SUBJECTIVE"
}
console.log(`response Text is ${response.text()}`)
return Promise.resolve(response)
}
export {
fetchNewsData
}
Thank you!
I found the answer...
Misread document -> the mock folder has to be in the same directory as the file being mocked. I had put it in src.
I didn't expect folder location to be the issue!
Related
I have to add unit testing to legacy code where I can make no changes inside the code hence can't refactor the code to add async/await or increase the jest version from 25.0.0
code file (sample code of actual implementation):
window.getUsers = function(){
$.get(url)
.then(data => {
data.forEach(val => {
$(".box-user .box-content").append("<h1>hello</h1>");
console.log('box users content code file',document.querySelector('.box-users > .box-content').innerHTML);
})
})
.catch(err => {})
}
test case i am trying to run
import path from 'path';
import '#testing-library/jest-dom/extend-expect';
const fs = require('fs');
const html = fs.readFileSync(path.resolve(__dirname, './code-file.html'),'utf8');
const $ = require('jquery');
const mockResponse = {
"data": [
{
"id": "test id",
"name": "test name",
"surname": "test surname",
"jobTitle": "test job title",
}
],
"length": 1
};
describe("code-file",()=>{
document.documentElement.innerHTML = html;
it("api mocking and appending html ",()=>{
$.get = jest.fn().mockImplementation(() => {
return Promise.resolve(mockResponse);
});
let {getUsers} = require("./code-file");
getUsers();
let boxUsersHtml = document.querySelector(".box-users > .box-content").innerHTML;
console.log('box users content testing file',boxUsersHtml)
})
})
as you can see inner html for testing code is empty while I do see inner html of code file to have some value. I believe this is due to the async behavior where in the test case is complete and the html has not been appended yet because it is present inside a then block.
need to know how to execute then block before any assertions(before console in the above code) are made without making changes in actual code.
done function did not help link for reference testing async code
I am using cypress.io to test an API(Created using Node.js). I want to extract value from JSON response of the API and save it to a variable.
I have tried solutions mentioned in the below links it did not work:
Cypress - get value from json response body
Below is the code i am using to test the API:
/// <reference types="cypress" />
describe("Testing Provider Catalog API", () => {
it("Provider Catalog API GET Request", () => {
cy.request('GET', 'v1/providers')
.then((response) => {
expect(response).to.have.property('status', 200)
expect(response.body).to.not.be.null
// expect(response.body.providers).to.have.length(1)
})
cy.screenshot()
})
it("Provider Catalog API POST Request", () => {
const provider = {
"type": "loadboard",
"name": "123loadboard"
};
cy.request('POST', 'v1/providers', provider)
cy.screenshot()
})
it("Provider Catalog API PUT Request", () => {
const provider = {
"type": "loadboard",
"name": "123loadboard"
};
cy.request('PUT', 'v1/providers/61a54a66a2b734859481931c', provider)
cy.screenshot()
})
it("Provider Catalog API DELETE Request", () => {
cy.request('DELETE', 'v1/providers/61a68e7ca6011e605029191b')
cy.screenshot()
})
})
Below is the code that i am using
var providerId
cy.wait('#newObject').then((response) => {
expect(response.status).to.eq(201)
expect(response.responseBody).to.have.property('_id')
const body = (response.responseBody)
providerId = body['_id']
})
cy.get(someInput).type(newId)
Sample output of the API:
{
"_id":"61a54ba1a2b7348594819323",
"type":"loadboard",
"name":"123loadboard",
"__v":0
}
I want to store the value of the _id in a variable and use it later. I have been trying to for the last couple of days and nothing seems to work. Can anyone please help me. Thanks in advance.
The recommended way to use variables with cypress is with aliases. See docs here.
In your code, you can wrap() your _id and save it as an alias, then call your alias somewhere else in your code:
cy.wait('#newObject').then((response) => {
expect(response.status).to.eq(201)
expect(response.responseBody).to.have.property('_id')
cy.wrap(response.responseBody._id).as('newId')
})
// then later in your code use:
cy.get('#newId').then((newId) => {
cy.get(someInput).type(newId)
})
You could also type() your _id inside your wait():
cy.wait('#newObject').then((response) => {
expect(response.status).to.eq(201)
expect(response.responseBody).to.have.property('_id')
cy.get(someInput).type(response.responseBody._id)
})
Or you can use cypress global environmment object Cypress.env(). See docs here.
cy.wait('#newObject').then((response) => {
expect(response.status).to.eq(201)
expect(response.responseBody).to.have.property('_id')
Cypress.env('newId', response.responseBody._id)
})
// then later in your code use:
cy.get(someInput).type(Cypress.env('newId'))
I have a json, viewable at https://imgur.com/a/F3kV29F
or here https://dweet.io/get/dweets/for/shyam__5
In python, I am able to print the yearlyWatts by doing:
print(collection[1]['content']['yearlyWatts'])
where collection is the json, done by:
collection = (dweepy.get_dweets_for('shyam__5'))
I am trying to do the same thing in Javascript. Currently, I have done:
getCryptoCurrencyInfo(5)
.then(currencyInfo => {
console.log(currencyInfo[1].yearlyWatts)
This does not work, I get no output.
Please do not pay attention to the function getCryptoCurrencyInfo, I would really appreciate if someone could tell me what to write in the console.log(HERE) in order to output the yearly watts of 111255.51
Any help would be appreciated. Thanks!
Suppose you want a single yearlyWatt.
const data = {
"this": "succeeded",
"by": "getting",
"the": "dweets",
"with": [{
"thing": "shyam__5",
"created": "2020-07-03T08:38:01.184Z",
"content": {
"test": "test"
}
},
{
"thing": "shyam__5",
"created": "2020-07-03T08:37:58.068Z",
"content": {
"yearlyWatts": 111429.4
}
}
]
}
console.log(data.with[1].content.yearlyWatts)
I figured out how to do it thanks to xMayank's help.
In the backend module, the code is:
import { fetch } from 'wix-fetch'
export function getCryptoCurrencyInfo() {
const url = 'https://dweet.io/get/dweets/for/shyam__5'
console.log(url)
return fetch(url, { method: 'get' }).then(response => response.json())
}
To get it to work, the site page (front end) says this:
// For full API documentation, including code examples, visit https://wix.to/94BuAAs
import { getCryptoCurrencyInfo } from 'backend/serviceModule'
import { fetch } from 'wix-fetch'
$w.onReady(function() {
//TODO: write your page related code here...
getCryptoCurrencyInfo().then(currencyInfo => {
const data = currencyInfo
console.log(data.with[1].content.yearlyWatts)
console.log(data.with[2].content.monthlyWatts)
console.log(data.with[3].content.currentDailyCarbonSaved)
console.log(data.with[4].content.currentDailyWatts)
})
})
considering global_obj your json_object, you can do this
global_obj.with.find(element => element.thing==="shyam__5");
I am trying to open, read and return an HTML files using Azure functions. I am developing locally and the logs says that the function executed successfully however on the browser I am getting 500 internal server error. Am I doing something wrong in here?
const fs = require('fs');
const path = require('path');
const mime = require('../node_modules/mime-types');
module.exports = function (context, req) {
const staticFilesFolder = 'www/build/';
const defaultPage = 'index.html';
getFile(context, req.query.file);
function getFile(context, file) {
const homeLocation = process.env["HOME"];
if(!file || file == null || file === undefined){
context.done(null,{status:200,body:"<h1>Define a file</h1>",headers:{
"Content-Type":" text/html; charset=utf-8"
}});
}
fs.readFile(path.resolve(path.join(homeLocation, staticFilesFolder, file)),
(err, htmlContent) => {
if (err) {
getFile(context, "404.html");
}
else {
const res = {
status: 200,
body: htmlContent,
headers:{
"Content-Type": mime.lookup(path.join(homeLocation, staticFilesFolder, file))
}
}
context.done(null,res);
}
})
}
};
Note
I am sure that 404.html exists and index.html exists. When I log the contents of htmlContent it is giving the correct output.
functions.json
{
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"methods":["get"],
"route":"home",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
Response on Chrome
If I removed "Content-Length" header the status code changes to 406.
Update 1 The code seems to be running normally on Azure Portal but it is not working when running it locally.
It looks like you are combining two methods of returning data from an http triggered function(context.res and context.done()): https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-node#accessing-the-request-and-response
Since you are using context.res, try removing context.done();
You are making an incorrect use of context.res, you shouldn't be overwriting it but instead leveraging the methods provided by the Response class provided in the Azure NodeJS worker. If you are using using VSCode you'll get intellisense for these methods. Otherwise see: https://github.com/Azure/azure-functions-nodejs-worker/blob/dev/src/http/Response.ts
Your code should look something like this instead.
context.res.setHeader('content-type', 'text/html; charset=utf-8')
context.res.raw(htmlContent)
Using context.res.raw or context.res.send will already perform the context.done call for you.
Make sure you use content-type=text/html; charset-utf8 instead of content-type=text/html or you'll trigger an issue with the returned content-type. Instead of returning content-type=text/html you end up getting content-type=text/plain which will fail to render your html.
Addressed on: https://github.com/Azure/azure-webjobs-sdk-script/issues/2053
I have the following message, just before a failing test
Below is my piece of code
before(function(done) {
function afterListening() {
customFormats(ZSchema);
done();
}
if (app.server.listening) return afterListening();
app.on('listening', afterListening);
});
describe('/a1/{exampleID}', function() {
describe('get', function() {
it('should respond with 200 Return an array of shelter...', function(done) {
/*eslint-disable*/
var schema = {
"type": [
"object",
"null"
],
"properties": {
"meta": {
"type": [
"object",
"null"
],
"properties": {
"resource": {
"type": [
"string",
"null"
],
"description": "fully qualified URL call"
},
"version": {
"type": [
"string",
"null"
],
"description": "version of API being called"
},
"response": {
"type": [
"integer",
"null"
],
"format": "int32",
"description": "status code"
},
"required": [
"version",
"resource"
]
}
}
};
/*eslint-enable*/
api.get('/a1/example/64442')
.set('Content-Type', 'application/json')
.expect(200)
.end(function(err, res) {
if (err) return done(err);
validator.validate(res.body, schema).should.be.true;
done();
});
});
});
});
Error
1) example "before each" hook:
Error: timeout of 200ms exceeded. Ensure the done() callback is being
called in this test.
at null. (lib/runnable.js:170:19)
This error came only when I run the test case on my machine.If I run the same test case in another machine the test case is passing. why it happens.It's weird to see like this.
Any help, please!!
You generally receive timeout error, when you are not returning a promise as expected.
Done is the older implementation of the same, but no longer required. If you are using a recent version of Mocha, you should be able to just return the promise instead of calling Done().
Here are details on mocha-as-promised - which was integrated with default Mocha, since version 1.18.0.
Example of how you should return a promise:
it("should be fulfilled with 5", function () {
return promise.should.become(5);
});
In case of beforeeach - implementation should look like this:
beforeEach(() => {
const {col1, comments} = mongoose.connection.collections;
return col1.drop(() => {
// Do something after collection is dropped
});
});
Notice return for the action taken within beforeeach.
Can you please share your beforeEach with us so we can help?
Without looking, it might be because your connection to whatever thing you're connecting to isn't responding on time or isn't responding at all.
Might wanna check your connection to places where your unit tests are connecting (chances are it's the database, because it's in beforeEach() and beforeEach() doesn't require a done() to be called inside it.
Increase your timeout to something like 10 seconds or such. If you don't get database errors then, your connection is slow. If you still get timeout errors even at 10 seconds, you might have no connection at all.