Jest/Supertest errors with TypeError: app.address is not a function
Firstly, I have tried the answer here - didn't help to resolve, the accepted answer didn't resolve my issue.
I am trying to test my API endpoints with Jest/Supertest. Starting with a simple /test endpoint. However when I run the tests, I get:
TypeError: app.address is not a function
.
app.js
:
...
// Set server (default to 3000)
app.set('port', process.env.PORT || 3000);
// Start server
const server = http.listen(app.get('port'), () => {
logger.info(`Worker ${process.pid} running on ${app.get('port')} in ${app.get('env')} mode`);
});
module.exports = server;
...
app.test.js
:
const server = require('./app');
const supertest = require('supertest');
const request = supertest(server);
it('Gets the test endpoint', async (done) => {
// Sends GET Request to /test endpoint
const res = await request.get('/test');
done();
});
Test run output:
FAIL ./app.test.js
✕ Gets the test endpoint (24 ms)
● Gets the test endpoint
TypeError: app.address is not a function
14 | it('Gets the test endpoint', async (done) => {
15 | // Sends GET Request to /test endpoint
> 16 | const res = await request.get('/test');
| ^
17 |
18 | // ...
19 | done();
Any input would be welcome, thanks.
1 answer
-
answered 2021-01-14 16:56
Kuyashii
Comment from @jonrsharpe above was the correct answer:
Supertest takes the app, not the server. You don't need to listen, it sets up the port for you (that's one of the benefits - stackoverflow.com/a/62992056/3001761). I'd recommend splitting up the app and the server parts, as I've done here https://github.com/textbook/starter-kit/tree/1567d269b8afe5d93408202900ac0ac1473fd89e/server
See also questions close to this topic
-
clear cart from session , and after logging it to console i get empty array but when visit cart view i still get cart items
I am working on e-commerce project , after checkout i wrote a code that deletes the cart items , and just to make sure i console.log(req.session.cart), and it shows an empty array means that session.cart is empty , but then i redirect user to home page , but then on home page i still get cart and its items , how to solve this problem? thanks .
this is how i cleared my cart its working fine!
order.save().then((r) => { // console.log(r) console.log("after checkout") for (let index = 0; index < req.session.cart.length; index++) { req.session.cart.splice(index) } console.log("Cart after clearing items ") console.log(req.session.cart
but if I revisit my cartView route i still get cart adn its items
router.get('/viewCarts', (req, res) => { console.log("cart items ",req.session.cart) catSchema.find({}).then((categories) => { // console.log(req.session.cart) res.render('../views/cartView/cartView.ejs', { layout: '../views/welcome/welcomeHeader.ejs', options: 'BUY', title: 'MY CART', cat: categories, cart:req.session.cart }); }); });
-
Stripe POST request with Authentication code
Server Side:
// Set your secret key. Remember to switch to your live secret key in production! // See your keys here: https://dashboard.stripe.com/account/apikeys const Stripe = require('stripe'); const stripe = Stripe('sk_test_xxxxxx'); const response = await stripe.oauth.token({ grant_type: 'authorization_code', code: 'ac_123456789', }); var connected_account_id = response.stripe_user_id;
Client Side:
How can i create a POST request to receive the
connected_account_id
Documentation info: https://stripe.com/docs/connect/oauth-standard-accounts
-
I'm using Windows 10 and I can't seem to use set the environment variable on nodejs on my terminal
I'm a beginner to nodejs. I created two json files with different names and mail.host. The first one is called development.json
{ "name": "My Express App - Development", "mail": { "host": "dev-mail-server" } }
and the other one is production.json{ "name": "My Express App - Production", "mail": { "host": "prod-mail-server" } }
after using executing this code below on my index.js, the terminal prints the same output even after using set NODE_ENV="production" in the terminal. What seems to be the problem in my code? Thank you so much!console.log(
Application Name: ${config.get('name')}
) console.log(Mail Server: ${config.get('mail.host')}
) -
how can i send message to particular user using socket io in mern app
this is my messageschema i want to send messages to particular user with socket io and im using mern stack for it im new to socket how can i send message to particular users one to one and how can i handle it in react
const MessageSchema = mongoose.Schema({ conversation:{ type: Schema.Types.ObjectId, ref: 'conversations', }, to:{ type:Schema.Types.ObjectId, ref:'user', }, from:{ type:Schema.Types.ObjectId, ref:'user', }, body: { type: String, required: true, }, createdAt: { type: Date, default: Date.now() } })
this is my message component.here i have list of users who are currnt users friends how can i send msg to particular user using socket and storre messages in message schema
import React, { Component } from 'react'; import { Link,Redirect } from 'react-router-dom'; import UserService from "../services/userservice"; import {getUsersFriend} from "../services/messageservice"; import io from "socket.io-client"; const SOCKET_IO_URL = "http://localhost:4000/"; const socket = io(SOCKET_IO_URL); export default class Messages extends Component { constructor(props){ super(props) this.state = { currentUser: UserService.getCurrentUser(), isLoading:false, userdetails:[], show:false, username:'' }; } componentDidMount(){ this.fetchUser() socket.on('connection',data => { console.log("connection",data) }) } async fetchUser(){ try{ const {currentUser} = this.state console.log(currentUser) const data = { userid : currentUser.user._id } console.log(data) let user = await getUsersFriend(data) this.setState({ userdetails: user }); console.log(user) }catch(err){ console.log(err) } } showMessageSpace(elementusername){ this.setState({ show: true, username:elementusername }); console.log(elementusername) } render(){ const { currentUser ,isLoading,userdetails } = this.state; if (isLoading) { return (<div><p>Loading...</p></div>); } if(!currentUser){ return( <div> <Redirect to='/login' /> </div> ) } else{ return( <div> <h1>Messages</h1> <div> <p>Users</p> {' '} <ul className="collection"> {userdetails.map((element) => { return( <div key={element._id}> <li>{element.username}{' '}<input type="button" id={element._id} value="Message" onClick={this.showMessageSpace.bind(this,element.username)} ></input></li> </div> ); }) } </ul> {' '} </div> {' '} <Link to="/dashboard">Dashboard</Link> {' '} <div> { this.state.show && (<div> <h2>Username : {' '}{this.state.username}</h2> {' '} <div> Body </div> {' '} {' '} <div> {' '} <input type="text"></input> <button>Send</button> </div> {' '} </div>) } </div> </div> ) } } }
-
how to add external css file in ejs file on express.js ? i have tried everything present on internet till 2021
Please help me here, it is very simple yet I cannot display css from external file in ejs. the page is displaying but without css. i have tried every solution on stackoverflow till 2021, youtube etc, none of their tutorials work on my device but on their it works. In my output, the css should make the text colour red but its not working like that. My project structure is this- (pic) see-file-structure
for file-structure see pic or see below
./public/css/style.css
./views/index.ejs
./app.js
my app.js , ejs file and css file code is below.
app.js
const express = require('express'); const app = express(); const port = process.env.PORT || 2997; app.set('view engine', 'ejs'); app.use(express.static(__dirname + '/public')); app.get("/", (req,res) => { res.render('index'); }) app.listen(port, ()=> { console.log('listening on port'); });
ejs file-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link href="/css/style.css" rel="stylesheet" type="txt/css"> </head> <body> <h1> hello world </h1> </body> </html>
css file-
h1 {color: red};
package.json file-
"main": "app.js", "dependencies": { "ejs": "^3.1.6", "express": "^4.17.1",
-
Paramater value '<' converted to '<'
I am using ExpressJS with body-parser library.
When I pass a param value 2<5 then it is converted to
2<5
read: async (req, res, next) => { try { let condition= req.query.condition|| req.body.condition // condition= 2<5
-
Adjacent sibling selector with Enzyme dose NOT work
I have html like below:
<input type ="text" id="textInput-FirstName" /> <div class="col error">warning Message</div>
I am trying to get the "warning Message", so I use the code below:
expect(wrapper.find('#textInput-FirstName + div').text()).toBe('warning Message');
But I got an error in the console saying "Method “text” is meant to be run on 1 node. 0 found instead."
I use the $('input#textInput-FirstName + div') in the console in chrome browser and it can find the node. I have no idea why it doesn't work with enzyme. Could anyone tell me is there something wrong? I use “expect(wrapper.find('.error').text()).toBe('warning Message')” and it works fine, but I need to use "input#textInput-FirstName + div" because I have another familiar nodes.
I use "react": "^16.9.0", "jest": "^24.9.0", "enzyme": "^3.11.0"
-
Ts and jest Best way to test routes
I'm starting with jest, and I'm trying to test a route, but I don't know what is the best way to do this, well the way I did it with docker, I go up the docker and start the server express but in my test i create it again and i'm getting my port already in use:
● Hello Word Route › should return a json with value: hello word listen EADDRINUSE: address already in use :::8080 50 | 51 | public start(): void { > 52 | this.server = this.express.listen(Number(process.env.APP_PORT) || 8080, () => {
I have the following bootstrap to start my server:
class ApplicationServer implements Server { private express: Application; private logger: LoggerProvider; private server: http.Server constructor(logger: LoggerProvider) { this.express = express(); this.logger = logger; } public getExpress(): Application { return this.express } public getLogger():LoggerProvider { return this.logger; } public getServer():http.Server { return this.server; } public async close(): Promise<void> { try { this.logger.log(`info`, `closing the http server`, {}) this.server.close() this.logger.log(`info`, `Http server successfully closed`, {}) this.logger.log(`info`, `closing the database`, {}) await closeDB(); this.logger.log(`info`, `Database successfully closed`, {}) } catch (error) { this.logger.log(`error`, error.message, error) } } public async init(): Promise<void> { setupStaticFiles(this.express); setupMiddlewares(this.express); setupRoutest(this.express, this.logger); await connectDB(this.logger) } public start(): void { this.server = this.express.listen(Number(process.env.APP_PORT) || 8080, () => { this.logger.log( `info`, `Server listening on port: ${process.env.APP_PORT || 8080}`, {} ); }); } } export default ApplicationServer;
factory:
export const SetupServer = (): Server => { const logger = new adptLogger({}) return new ApplicationServer(logger) }
start:
(async () => { const server = SetupServer(); try { await server .init() .then(() => server.start()) } catch (error) { console.error(error) server.getLogger().log(`error`, error.message, error) process.exit() } })();
and this is my test::
describe("Hello Word Route", () => { let server= {} as Server; beforeAll(async () => { server = SetupServer(); await server.init(); server.start(); }); afterAll(async () => { }); it("should return a json with value: hello word", async () => { await request(server.getExpress()) .post("api/hello-word") .send({hello: 'hello word'}) .set('Accept', 'application/json') .expect('Content-Type', /json/) .expect(200); }); });
I would like to know what is the best practice to take in this situation to perform route tests my test fail:
Hello Word Route › should return a json with value: hello word listen EADDRINUSE: address already in use :::8080 50 | 51 | public start(): void { > 52 | this.server = this.express.listen(Number(process.env.APP_PORT) || 8080, () => { | ^ 53 | this.logger.log( 54 | `info`, 55 | `Server listening on port: ${process.env.APP_PORT || 8080}`, at Function.listen (node_modules/express/lib/application.js:618:24) at ApplicationServer.start (src/application/infra/app.ts:52:32) at Object.<anonymous> (src/application/routes/hello-word-routes.test.ts:11:12) (node:113) UnhandledPromiseRejectionWarning: Error: connect ECONNREFUSED 127.0.0.1:80 at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1146:16) (Use `node --trace-warnings ...` to show where the warning was created) (node:113) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1) (node:113) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
-
Simulate Width to Test Responsive React Components
There is a
Drawer
and aButton
which opens theDrawer
. TheButton
and theDrawer
only appear in the DOM when the window width is less than 600.This is the
Drawer
andButton
code.<Hidden smUp> <Button className={classes.button} variant="outlined" color="secondary" endIcon={<Menu />} onClick={toggleDrawer(true)} data-testid="DrawerMenuButton" > Menu </Button> <SwipeableDrawer anchor="left" open={open} onClose={toggleDrawer(false)} onOpen={toggleDrawer(true)} disableDiscovery data-testid="Drawer" > <div className={classes.list}> <List data-testid="DrawerMenuList"> {drawerItems.map(({ icon: Icon, label, onClick }, index) => ( <ListItem key={index} button {...{ onClick }}> <ListItemIcon> <Icon /> </ListItemIcon> <ListItemText primary={label} /> </ListItem> ))} </List> </div> </SwipeableDrawer>
When running
screen.debug()
during tests, this is the output<body> <div /> </body>
meaning that the width is not within the range for the components to appear.
How can the right width be set?
-
Success Test Hanging the Jenkin Build
I am new to Jenkin with Supertest and Mocha. I am running a test script and build a script in Jenkin. My test is Success but the Build is hanging up.
Test Script of supertest npm:
var request = require('supertest'); var app = require('../index.js'); describe('GET /', function() { it('Respond with hello world', function(done) { //navigate to root and check the the response is "hello world" request(app).get('/').expect({ status : true, message : 'hello world' }, done); }); });
Here is the Screenshot of Jenkin Log:
Could anybody help?
-
More than one test fails due to import after jest is torn down - Supertest Typescript and Express API
I am running into an issue where I am running multiple tests using
supertest
andjest
. When there is only one test running then it works just fine but the second one throws the following error:ReferenceError: You are trying to `import` a file after the Jest environment has been torn down.
I tested this with two very simple tests:
describe("Default API", () => { describe("Default:", () => { it("should create a user in the DB", (done) => { request(app).get("/").expect(200, done); }); it("should create a user in the DB", (done) => { request(app).get("/").expect(200, done); }); }); });
They are the same but the second one throws the error. If I run only the first one there is no issue. This must be a setup issue Does anyone have advice. In my index.ts where I have the main express code I export app as follows:
export default app;
This is at the bottom of the index.ts file.
-
How to mock multer using jest/enzyme to file upload using axios post mock call
I am testing my express router with
axios
post-call to backend. I am getting500
responses instead of 200, not sure how to mock themulter
effectively. Any thoughts on this? Thanksroutes.jsx
const axios = require('axios') const router = express.Router() const multer = require('multer') const FormData = require('form-data') const express = require('express') const upload = multer({ storage: multer.memoryStorage() }).any() router.post('/', upload, (req, res) => { const formData = new FormData() const { body } = req req.files.forEach(file => { formData.append( 'files', file.buffer, { filename: file.originalname }, file.originalname ) }) axios .post('/api/endpoint', formData) .then(response => {return response }) .catch(e => { console.log(e) }) }) module.exports = router
Below are my test case
routes.jsx.test
const axios = require('axios') const MockAdapter = require('axios-mock-adapter') const myroute = require('myroute') const app = express() const mock = new MockAdapter(axios) const request = require('supertest') const express = require('express') const bodyParser = require('body-parser') const multer = require('multer') jest.mock('multer') multer.mockImplementation(() => { return { any () { return (req, res, next) => { req.body = { userName: 'testUser' } req.files = [ { originalname: 'sample.name', mimetype: 'sample.type', path: 'sample.url' } ] return next() } } } }) app.use(bodyParser.json()) app.use('/', myroute) describe('sendFiles', () => { const url = '/api/endpoint' test('200 response', () => { const myMockRes = { mykey: 'myVal' } let formData = new FormData() const file = new Blob(['somee contents'], { type: 'multipart/form-data' }) formData.append('files', file) formData.append('userName', 'testUser') mock.onPost(url).reply(200, myMockRes) return ( request(app) .post('/') .send({ userName: 'testUser', files: [file] }) //.expect('Content-Type', /json/) .expect(200) .then(response => { const { data } = response.body expect(data).toEqual(myMockRes) }) ) }) })
error:
TypeError: Cannot read property 'any' of undefined in routes.jsx const upload = multer({ storage: multer.memoryStorage() }).any()