মোচা এপিআই টেস্টিং: 'টাইপ এরির: অ্যাপ.এড্রেস কোনও ফাংশন নয়' পাওয়া


105

আমার ইস্যু

আমি একটি খুব সাধারণ সিআরইউডি এপিআই কোড করেছি এবং আমি সম্প্রতি কিছু পরীক্ষা ব্যবহার করে কোডিংও শুরু করেছি chaiএবং chai-httpআমার পরীক্ষাগুলি চালানোর সময় আমার সমস্যা হচ্ছে $ mocha

আমি যখন পরীক্ষা চালাচ্ছি আমি শেলটিতে নিম্নলিখিত ত্রুটিটি পেয়েছি:

TypeError: app.address is not a function

আমার কোড

এখানে আমার পরীক্ষার একটির নমুনা দেওয়া হয়েছে ( /tests/server-test.js ):

var chai = require('chai');
var mongoose = require('mongoose');
var chaiHttp = require('chai-http');
var server = require('../server/app'); // my express app
var should = chai.should();
var testUtils = require('./test-utils');

chai.use(chaiHttp);

describe('API Tests', function() {
  before(function() {
    mongoose.createConnection('mongodb://localhost/bot-test', myOptionsObj);
  });

  beforeEach(function(done) {
    // I do stuff like populating db
  });

  afterEach(function(done) {
    // I do stuff like deleting populated db
  });

  after(function() {
    mongoose.connection.close();
  });

  describe('Boxes', function() {

    it.only('should list ALL boxes on /boxes GET', function(done) {
      chai.request(server)
        .get('/api/boxes')
        .end(function(err, res){
          res.should.have.status(200);
          done();
        });
    });

    // the rest of the tests would continue here...

  });

});

এবং আমার expressঅ্যাপ্লিকেশন ফাইলগুলি ( /server/app.js ):

var mongoose = require('mongoose');
var express = require('express');
var api = require('./routes/api.js');
var app = express();

mongoose.connect('mongodb://localhost/db-dev', myOptionsObj);

// application configuration
require('./config/express')(app);

// routing set up
app.use('/api', api);

var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('App listening at http://%s:%s', host, port);
});

এবং ( /server/routes/api.js ):

var express = require('express');
var boxController = require('../modules/box/controller');
var thingController = require('../modules/thing/controller');
var router = express.Router();

// API routing
router.get('/boxes', boxController.getAll);
// etc.

module.exports = router;

অতিরিক্ত নোট

পরীক্ষা চালানোর আগে serverআমি /tests/server-test.js ফাইলে ভেরিয়েবল লগ আউট করার চেষ্টা করেছি :

...
var server = require('../server/app'); // my express app
...

console.log('server: ', server);
...

এবং আমি যে ফলাফলের একটি খালি বস্তুর হল: server: {}

উত্তর:


236

আপনি আপনার অ্যাপ্লিকেশন মডিউলে কোনও রফতানি করবেন না। আপনার app.js ফাইলটিতে এটি যুক্ত করার চেষ্টা করুন:

module.exports = server

36
আমার একমাত্র সমস্যাটি হ'ল কোনও পরীক্ষার জন্য ফিট করার জন্য অ্যাপ্লিকেশন কোডটি কখনও পরিবর্তন করা উচিত নয়।
dman

@ chovy আপনি কি এই সমাধান করেছেন? আমার নীচে আমার একটি বিকল্প আছে যা কাজ করেছিল।
স্কাইগার্ড

4
সম্ভাব্য সমস্যাটি এমন একটি সার্ভারের সাথে ডিল করছে যা একটি অ্যাসিঙ্ক পরিষেবাদি ধারণ করে, কারণ চই-এইচটিপি তার যুক্তিটি জানেন না এবং এটি আপনার সার্ভারটি সম্পূর্ণরূপে শুরু হওয়ার আগেই সরাসরি চলে যাবে
atom2ueki

4
@ নবস্কার এই ক্ষেত্রে সার্ভারটি সম্ভবত ইতিমধ্যে অ্যাপ্লিকেশন (...)
গার গডফ্রে

আপনার পরীক্ষাগুলির জন্য আপনি অ্যাপ্লিকেশন () যা প্রকৃত সার্ভার শুরু করে তা ব্যবহার করবেন না, পরিবর্তে http.createServer () ব্যবহার করুন
হোয়াঙ্কি

43

কেবলমাত্র ফাংশনের পরিবর্তে http.Serverপ্রত্যাশিত জিনিসটি রফতানি করা গুরুত্বপূর্ণ , অন্যথায় আপনি পাবেন ।app.listen(3000)appTypeError: app.address is not a function

উদাহরণ:

index.js

const koa = require('koa');
const app = new koa();
module.exports = app.listen(3000);

index.spec.js

const request = require('supertest');
const app = require('./index.js');

describe('User Registration', () => {
  const agent = request.agent(app);

  it('should ...', () => {

4
এটি কেন " http.Serverঅবজেক্টটি রফতানি করা গুরুত্বপূর্ণ" তা আপনার উত্তরে অন্তর্ভুক্ত করা উচিত ।
গ্রম্পি ক্রাউটন

@ গ্রম্পি ক্রাউটন আমি যুক্ত করেছি ত্রুটিটি অন্যথায় আপনি পাবেন
কিম কার্ন

4
ধন্যবাদ কিম। আমি আপনাকে একটি +1 দিয়েছি কারণ আমি মনে করি এটি আপনার উত্তরকে উন্নত করে। ভবিষ্যতে, আপনি ব্যাখ্যা করতে হবে কেন । কেউ এই প্রশ্নটি দেখছেন এবং তার মধ্যে কেবল প্রাথমিক জ্ঞান রয়েছে তা কল্পনা করুন, একটি ভাল চিন্তাভাবনা করা এবং ব্যাখ্যা করা উত্তর তাদের আরও শিখিয়ে দেবে।
গ্রম্পি ক্রাউটন

আপনার পরীক্ষাগুলির জন্য আপনি অ্যাপ্লিকেশন () যা প্রকৃত সার্ভার শুরু করে তা ব্যবহার করবেন না , পরিবর্তে http.createServer () ব্যবহার করুন
হোয়াঙ্কি

28

এটি সহায়তা করতে পারে এবং একটি পরীক্ষায় ফিট করতে অ্যাপ্লিকেশন কোড পরিবর্তন করার জন্য @ dman পয়েন্টকে সন্তুষ্ট করে।

প্রয়োজন অনুসারে লোকালহোস্ট এবং বন্দরে আপনার অনুরোধ করুন chai.request('http://localhost:5000')

পরিবর্তে

chai.request(server)

এটি কোয়া জেএস (ভি 2) এবং আভা জেএস ব্যবহার করে একই ত্রুটি বার্তাটি স্থির করেছে।


4
এই ত্রুটিটি করার পরে আসছে না, তবে তথ্যটি নাল এবং স্ট্যাটাসকোডে আসছে 200 ঠিক আছে।
অনিতা মেহতা

5

উপরের উত্তরগুলি সঠিকভাবে ইস্যুটিকে সম্বোধন করছে: কাজ করতে supertestচায় http.Server। তবে, app.listen()একটি সার্ভার পেতে কল করা একটি শ্রবণকারী সার্ভারও শুরু করবে, এটি খারাপ অভ্যাস এবং অপ্রয়োজনীয়।

আপনি এটি ব্যবহার করে কাছাকাছি যেতে পারেন http.createServer():

import * as http from 'http';
import * as supertest from 'supertest';
import * as test from 'tape';
import * as Koa from 'koa';

const app = new Koa();

# add some routes here

const apptest = supertest(http.createServer(app.callback()));

test('GET /healthcheck', (t) => {
    apptest.get('/healthcheck')
    .expect(200)
    .expect(res => {
      t.equal(res.text, 'Ok');
    })
    .end(t.end.bind(t));
});


1

আমাদের নোড + টাইপস্ক্রিপ্ট সার্ভারলেস প্রকল্পে ts-node ব্যবহার করে মোচা চালানোর সময় আমাদের একই সমস্যা ছিল।

আমাদের tsconfig.json এর "সোর্স ম্যাপ" ছিল: সত্য। সুতরাং উত্পন্ন, .js এবং .js.map ফাইলগুলির কারণে কিছু মজাদার ট্রান্সপ্লাইং সমস্যা হয় (এটির সমান)। আমরা যখন টিএস-নোড ব্যবহার করে মোচা রানার চালাই। সুতরাং, আমি সোর্স মানচিত্রের পতাকাটিকে মিথ্যাতে সেট করব এবং আমাদের এসসিআর ডিরেক্টরিতে সমস্ত .js এবং .js.map ফাইল মুছে ফেলব। তারপরে বিষয়টি চলে গেল।

আপনি যদি ইতিমধ্যে আপনার এসআরসি ফোল্ডারে ফাইল তৈরি করে থাকেন তবে নীচের কমান্ডগুলি সত্যই সহায়ক হবে।

src -name " .js.map " -exec rm {} \; src -name " .js" -exec rm {} \;


0

কেবলমাত্র যদি কেউ হাপিজ ব্যবহার করে তবে এখনও সমস্যাটি দেখা দেয় কারণ এটি এক্সপ্রেস.জেএস ব্যবহার করে না, সুতরাং ঠিকানা () ফাংশনটি বিদ্যমান নেই।

TypeError: app.address is not a function
      at serverAddress (node_modules/chai-http/lib/request.js:282:18)

এটি কাজ করতে workaround

// this makes the server to start up
let server = require('../../server')

// pass this instead of server to avoid error
const API = 'http://localhost:3000'

describe('/GET token ', () => {
    it('JWT token', (done) => {
       chai.request(API)
         .get('/api/token?....')
         .end((err, res) => {
          res.should.have.status(200)
          res.body.should.be.a('object')
          res.body.should.have.property('token')
          done()
      })
    })
  })

0

আমি জাস্ট এবং সুপারস্টেট ব্যবহার করছি, তবে একই ত্রুটিটি পেয়েছি। এটি কারণ এটি ছিল যে আমার সার্ভারটি সেটআপ করতে সময় নেয় (এটি সেটআপ ডিবি, কনফিগার পঠন ইত্যাদিতে অ্যাসিঙ্ক)। আমার জেস্ট ব্যবহার করা দরকারbeforeAllঅ্যাসিঙ্ক সেটআপটি চালানোর অনুমতি সাহায্যকারী । আমার শ্রোতাকে আলাদা করে শোনার জন্য আমার সার্ভারটিও রিফ্যাক্টর করতে হয়েছিল এবং পরিবর্তে পরীক্ষার সার্ভারটি তৈরি করার জন্য @ হোওহানকি পরামর্শটি ব্যবহার করুন।

index.js

export async function createServer() {
  //setup db, server,config, middleware
  return express();
}

async function startServer(){
  let app = await createServer();
  await app.listen({ port: 4000 });
  console.log("Server has started!");
}

if(process.env.NODE_ENV ==="dev") startServer();

test.ts

import {createServer as createMyAppServer} from '@index';
import { test, expect, beforeAll } from '@jest/globals'
const supertest = require("supertest");
import * as http from 'http';
let request :any;

beforeAll(async ()=>{
  request = supertest(http.createServer(await createMyAppServer()));
})

test("fetch users", async (done: any) => {
  request
    .post("/graphql")
    .send({
      query: "{ getQueryFromGqlServer (id:1) { id} }",
    })
    .set("Accept", "application/json")
    .expect("Content-Type", /json/)
    .expect(200)
    .end(function (err: any, res: any) {
      if (err) return done(err);
      expect(res.body).toBeInstanceOf(Object);
      let serverErrors = JSON.parse(res.text)['errors'];
      expect(serverErrors.length).toEqual(0);
      expect(res.body.data.id).toEqual(1);
      done();
    });
});

সম্পাদনা করুন:

ব্যবহার করার সময় আমারও ত্রুটি ছিল data.foreach(async()=>..., for(let x of...আমার পরীক্ষাগুলিতে ব্যবহার করা উচিত

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.