原始代码可以提供错误代码500,但原始代码可以正常工作

时间:2019-03-06 11:56:23

标签: javascript node.js mocha tdd chai

我正在尝试修改我的代码,以便它可以继续执行代码环境,代码环境坚持要求我对我所做的重复代码进行修改,但是说,当原始代码可以正常工作时,折射代码给出了错误500,这是我的代码

// data structure as dummy database
class BookAMeal {
  constructor() {
    this.mealOptionList = [];
    this.menuList = [];
    this.orderList = [];
  }

  mealFormat(data) {
    this.mealOptionData = {
      id: data.mealId,
      name: data.mealOptionName,
      price: parseInt(data.mealOptionPrice, 10),
    };
    return this.mealOptionData;
  }

  totalPriceMenu(optionOneArray, optionTwoArray) {
    this.total = 0;
    optionOneArray.forEach((optionOne) => {
      optionTwoArray.forEach((optionTwo) => {
        if (optionOne === optionTwo.name) {
          this.total += optionTwo.price;
        }
      });
    });
    return this.total;
  }

  totalPriceOrders(optionOneArray, optionTwoArray) {
    this.total = 0;
    optionOneArray.forEach((optionOne) => {
      optionTwoArray.forEach((optionTwo) => {
        if (optionOne === optionTwo.name) {
          this.total += optionTwo.total;
        }
      });
    });
    return this.total;
  }

  menuFormat(data) {
    this.menuOptions = data.menuOptions.split(' ');
    this.menuData = {
      date: new Date(),
      id: data.menuId,
      name: data.menuName,
      mealOptions: this.menuOptions,
      total: this.totalPriceMenu(this.menuOptions, this.mealOptionList),
    };
    return this.menuData;
  }

  orderFormat(data) {
    this.orderMenus = data.menuList.split(' ');
    this.orderData = {
      id: data.orderId,
      customer: data.customerName,
      menu: this.orderMenus,
      total: this.totalPriceOrders(this.orderMenus, this.menuList),
    };
    return this.orderData;
  }
}

const data = new BookAMeal();
export default data;

// meals controller for POST route that works fine with both mocha and POSTMAN after refracting
import data from '../models';
import services from '../services';
// @ts-ignore
import bookAMeal from './index';

bookAMeal.addOneMealOption = async (req, res) => {
  services.createOne(res, data.mealOptionList, data.mealFormat(req.body),
    'Success! Meal option created', req.body.mealOptionName, req.body.mealOptionPrice,
    (/^[A-Za-z]+$/).test(req.body.mealOptionName), (/^[0-9]+$/).test(req.body.mealOptionPrice),
    'Meal option name', 'Meal option price', services.mustBeNumbersErr('Meal option price'));
};

export default bookAMeal.addOneMealOption;

// menu controller for POST route that gives error 500 during testing with mocha and POSTMAN when refracted like above meals controller 
import data from '../models';
import services from '../services';
// @ts-ignore
import bookAMeal from './index';

bookAMeal.setMenu = async (req, res) => {
  services.createOne(res, data.menuList, data.menuFormat(req.body),
    'Success! Menu created', req.body.menuName, req.body.menuOptions,
    (/^[A-Za-z]+$/).test(req.body.menuName), (/^[A-Za-z\s]+$/).test(req.body.menuOptions),
    'Menu name', 'Menu options', services.stringToArrayErr('Menu options'));

// commented code below passes with both mocha and POSTMAN but needs to be refracted to pass code climate
  /*
    const testSetMenu = services.testItem(req.body.menuName, req.body.menuOptions, (/^[A-Za-z]+$/).test(req.body.menuName), (/^[A-Za-z\s]+$/).test(req.body.menuOptions));
    if (testSetMenu) {
      services.createOneRes(res, data.menuList, data.menuFormat(req.body), 'Success! Menu created');
      return;
    }
    services.processErr(req.body.menuName, req.body.menuOptions, 'Menu name', 'Menu options', services.stringToArrayErr('Menu options'), res);
    */
};

export default bookAMeal.setMenu;

// services that is called by all controllers including the above 2
class Services {
  async getAll(dataRes, dataMessage, array) {
    this.data = array;
    dataRes.status(200).send({
      message: dataMessage,
      data: this.data,
    });
  }

  findOne(dataParams, arrayData) {
    this.findItem = arrayData.find(item => item.id === parseInt(dataParams.id, 10));
    return this.findItem;
  }

  testItem(dataOne, dataTwo, dataOneTest, dataTwoTest) {
    this.testResult = (dataOne && dataTwo && dataOneTest && dataTwoTest) === true;
    return this.testResult;
  }

  async createOneRes(dataRes, arrayData, dataFormat, dataMessage) {
    this.createdItem = await dataFormat;
    this.createdItem.id = arrayData.length;
    await arrayData.push(this.createdItem);
    dataRes.status(201).send({
      message: dataMessage,
      data: this.createdItem,
    });
  }

  async createOne(dataRes, arrayData, dataFormat, dataMessage, dataOne,
    dataTwo, dataOneTest, dataTwoTest, nameOne, nameTwo, dataTwoTestRes) {
    this.testCreate = this.testItem(dataOne, dataTwo, dataOneTest, dataTwoTest);
    if (this.testCreate) {
      this.createOneRes(dataRes, arrayData, dataFormat, dataMessage);
      return;
    }
    this.processErr(dataOne, dataTwo, nameOne, nameTwo, dataTwoTestRes, dataRes);
  }

  async updateOne(dataRes, arrayData, dataFormat, dataMessage, updateId) {
    this.updatedItem = await dataFormat;
    this.updatedItem = updateId;
    await arrayData.splice(updateId, 1, this.updatedItem);
    dataRes.status(200).send({
      message: dataMessage,
      data: this.updatedItem,
    });
  }

  async deleteOne(dataRes, arrayData, deleteId) {
    this.id = deleteId;
    await arrayData.splice(this.id, 1);
    dataRes.status(204).send({});
  }

  requiredNameErr(name) {
    this.message = {
      message: `Fail! ${name} is required`,
    };
    return this.message;
  }

  mustBeLettersErr(name) {
    this.message = {
      message: `Fail! ${name} must be letters`,
    };
    return this.message;
  }

  mustBeNumbersErr(price) {
    this.message = {
      message: `Fail! ${price} must be numbers`,
    };
    return this.message;
  }

  stringToArrayErr(name) {
    this.message = {
      message: `Fail! ${name} must be letters and seperated by spaces`,
    };
    return this.message;
  }

  sendErr400(message, dataRes) {
    this.error = dataRes.status(400).send(message);
    return this.error;
  }

  processErr(dataOne, dataTwo, nameOne, nameTwo, dataTwoTestRes, resData) {
    if (!dataOne) {
      this.sendErr400(this.requiredNameErr(nameOne), resData);
      return;
    }
    if ((/^[A-Za-z]+$/).test(dataOne) === false) {
      this.sendErr400(this.mustBeLettersErr(nameOne), resData);
      return;
    }
    if (!dataTwo) {
      this.sendErr400(this.requiredNameErr(nameTwo), resData);
      return;
    }
    this.sendErr400(dataTwoTestRes, resData);
  }
}

const services = new Services();

export default services;

// exported data seeding for tests
import chai, {
  expect,
} from 'chai';
import chaiHttp from 'chai-http';
import app from '../index';

import data from '../models';

class Data {
  async meals() {
    this.testId = 0;
    this.secondTestId = 0;
    this.thirdTestId = 0;

    this.testDataOne = {
      mealId: data.mealOptionList.length,
      mealOptionName: 'Dodo',
      mealOptionPrice: 100,
    };
    this.testDataTwo = {
      mealId: data.mealOptionList.length,
      mealOptionName: 'Rice',
      mealOptionPrice: 1000,
    };
    this.testDataThree = {
      mealId: data.mealOptionList.length,
      mealOptionName: 'Beans',
      mealOptionPrice: 10000,
    };

    this.addMealOne = await data.mealFormat(this.testDataOne);
    this.addMealTwo = await data.mealFormat(this.testDataTwo);
    this.addMealThree = await data.mealFormat(this.testDataThree);
    this.testDataList = [this.addMealOne, this.addMealTwo, this.addMealThree];
    await data.mealOptionList.push(...this.testDataList);
    this.testId += this.addMealOne.id;
    this.secondTestId += this.addMealTwo.id;
    this.thirdTestId += this.addMealThree.id;
  }

  async menus() {
    this.testId = 0;
    this.secondTestId = 0;
    this.thirdTestId = 0;

    this.testDataFour = {
      menuId: data.menuList.length,
      menuName: 'Launch',
      menuOptions: 'Rice Dodo',
    };
    this.testDataFive = {
      menuId: data.menuList.length,
      menuName: 'Dinner',
      menuOptions: 'Rice Beans',
    };
    this.testDataSix = {
      menuId: data.menuList.length,
      menuName: 'Breakfast',
      menuOptions: 'Beans Dodo',
    };

    this.addOne = await data.menuFormat(this.testDataFour);
    this.addTwo = await data.menuFormat(this.testDataFive);
    this.addThree = await data.menuFormat(this.testDataSix);
    this.testDataListTwo = [this.addOne, this.addTwo, this.addThree];
    await data.menuList.push(...this.testDataListTwo);
    this.testId += this.addOne.id;
    this.secondTestId += this.addTwo.id;
    this.thirdTestId += this.addThree.id;
  }

  async orders() {
    this.testId = 0;
    this.secondTestId = 0;
    this.thirdTestId = 0;

    this.testDataSeven = {
      orderId: data.orderList.length,
      customerName: 'Okezie',
      menuList: 'Breakfast Lunch',
    };
    this.testDataEight = {
      orderId: data.orderList.length,
      customerName: 'Frank',
      menuList: 'Breakfast Dinner',
    };
    this.testDataNine = {
      orderId: data.orderList.length,
      customerName: 'Obiedere',
      menuList: 'Lunch Dinner',
    };

    this.addFour = await data.orderFormat(this.testDataSeven);
    this.addFive = await data.orderFormat(this.testDataEight);
    this.addSix = await data.orderFormat(this.testDataNine);
    this.testDataListThree = [this.addFour, this.addFive, this.addSix];
    await data.orderList.push(...this.testDataListThree);
    this.testId += this.addFour.id;
    this.secondTestId += this.addFive.id;
    this.thirdTestId += this.addSix.id;
  }
}

const dataSetup = new Data();

export {
  expect,
  chai,
  chaiHttp,
  app,
  dataSetup,
};

// tests for meals controller that passes both mocha and POSTMAN
import {
  expect,
  chai,
  chaiHttp,
  app,
  dataSetup,
} from './index';

chai.use(chaiHttp);

describe('Test endpoint at "/v1/meals" to create a meal option with POST', () => {
  before(() => {
    dataSetup.meals();
    dataSetup.menus();
    dataSetup.orders();
  });
  it('should create a meal option at "/v1/meal" with post if all request data are valid', async () => {
    const testData = {
      mealOptionName: 'Dodo',
      mealOptionPrice: 10,
    };
    const response = await chai.request(app).post('/v1/meals').send(testData);
    expect(response).to.have.status(201);
    expect(response.body).to.be.an('object');
    expect(response.body).to.have.property('data');
    expect(response.body).to.have.property('message').equal('Success! Meal option created');
    expect(response.body.data).to.have.property('id');
    expect(response.body.data).to.have.property('name').equal(testData.mealOptionName);
    expect(response.body.data).to.have.property('price').equal(testData.mealOptionPrice);
  });

  it('should not create a meal option at "/v1/meals" with POST if meal option name in request does not exist', async () => {
    const testData = {
      mealOptionPrice: 10,
    };
    const response = await chai.request(app).post('/v1/meals').send(testData);
    expect(response).to.have.status(400);
    expect(response.body).to.be.an('object');
    expect(response.body).to.have.property('message').equal('Fail! Meal option name is required');
  });

  it('should not create a meal option at "/v1/meals" with POST if meal option name in request is an empty string', async () => {
    const testData = {
      mealOptionName: '',
      mealOptionPrice: 10,
    };
    const response = await chai.request(app).post('/v1/meals').send(testData);
    expect(response).to.have.status(400);
    expect(response.body).to.be.an('object');
    expect(response.body).to.have.property('message').equal('Fail! Meal option name is required');
  });

  it('should not create a meal option at "/v1/meals" with POST if meal option name in request are not letters', async () => {
    const testData = {
      mealOptionName: '0(}fieidfjd',
      mealOptionPrice: 10,
    };
    const response = await chai.request(app).post('/v1/meals').send(testData);
    expect(response).to.have.status(400);
    expect(response.body).to.be.an('object');
    expect(response.body).to.have.property('message').equal('Fail! Meal option name must be letters');
  });

  it('should not create a meal option at "/v1/meals" with POST if meal option price in request does not exist', async () => {
    const testData = {
      mealOptionName: 'Dodo',
    };
    const response = await chai.request(app).post('/v1/meals').send(testData);
    expect(response).to.have.status(400);
    expect(response.body).to.be.an('object');
    expect(response.body).to.have.property('message').equal('Fail! Meal option price is required');
  });

  it('should not create a meal option at "/v1/meals" with POST if meal option price in request is an empty string', async () => {
    const testData = {
      mealOptionName: 'Dodo',
      mealOptionPrice: '',
    };
    const response = await chai.request(app).post('/v1/meals').send(testData);
    expect(response).to.have.status(400);
    expect(response.body).to.be.an('object');
    expect(response.body).to.have.property('message').equal('Fail! Meal option price is required');
  });

  it('should not create a meal option at "/v1/meals" with POST if meal option price in request is NOT a number', async () => {
    const testData = {
      mealOptionName: 'Dodo',
      mealOptionPrice: 'p0{f(jf]',
    };
    const response = await chai.request(app).post('/v1/meals').send(testData);
    expect(response).to.have.status(400);
    expect(response.body).to.be.an('object');
    expect(response.body).to.have.property('message').equal('Fail! Meal option price must be numbers');
  });
});

// tests for menu controller that fails mocha at 'menu options does not exist' but passes with POSTMAN
import {
  expect,
  chai,
  chaiHttp,
  app,
  dataSetup,
} from './index';

chai.use(chaiHttp);

describe('Test endpoint at "/v1/menus" to set menus with POST', () => {
  before(() => {
    dataSetup.meals();
    dataSetup.menus();
    dataSetup.orders();
  });

  it('should set a menu at "/v1/menus" with post if all request data are valid', async () => {
    const testData = {
      menuName: 'Launch',
      menuOptions: 'Dodo Rice',
    };
    const response = await chai.request(app).post('/v1/menus').send(testData);
    expect(response).to.have.status(201);
    expect(response).to.be.an('object');
    expect(response.body).to.have.property('data');
    expect(response.body).to.have.property('message').equal('Success! Menu created');
    expect(response.body.data).to.have.property('id');
    expect(response.body.data).to.have.property('name').equal(testData.menuName);
    expect(response.body.data).to.have.property('total');
  });

  it('should not create a menu at "/v1/menus" with POST if menu name in request does not exist', async () => {
    const testData = {
      menuOptions: 'Dodo Beans',
    };
    const response = await chai.request(app).post('/v1/menus').send(testData);
    expect(response).to.have.status(400);
    expect(response.body).to.be.an('object');
    expect(response.body).to.have.property('message').equal('Fail! Menu name is required');
  });

  it('should not create a menu at "/v1/menus" with POST if menu name in request is an empty string', async () => {
    const testData = {
      menuName: '',
      menuOptions: 'Dodo Beans',
    };
    const response = await chai.request(app).post('/v1/menus').send(testData);
    expect(response).to.have.status(400);
    expect(response.body).to.be.an('object');
    expect(response.body).to.have.property('message').equal('Fail! Menu name is required');
  });

  it('should not create a menu at "/v1/menus" with POST if menu name in request are not letters', async () => {
    const testData = {
      menuName: '}04[}(odyr',
      menuOptions: 'Dodo Beans',
    };
    const response = await chai.request(app).post('/v1/menus').send(testData);
    expect(response).to.have.status(400);
    expect(response.body).to.be.an('object');
    expect(response.body).to.have.property('message').equal('Fail! Menu name must be letters');
  });

  it('should not create a menu at "/v1/menus" with POST if menu options in request does not exist', async () => {
    const testData = {
      menuName: 'Launch',
    };
    const response = await chai.request(app).post('/v1/menus').send(testData);
    expect(response).to.have.status(400);
    expect(response.body).to.be.an('object');
    expect(response.body).to.have.property('message').equal('Fail! Menu options is required');
  });

  it('should not create a menu at "/v1/menus" with POST if menu options in request is an empty string', async () => {
    const testData = {
      menuName: 'Launch',
      menuOptions: '',
    };
    const response = await chai.request(app).post('/v1/menus').send(testData);
    expect(response).to.have.status(400);
    expect(response.body).to.be.an('object');
    expect(response.body).to.have.property('message').equal('Fail! Menu options is required');
  });

  it('should not create a menu at "/v1/menus" with POST if menu options in request are not letters', async () => {
    const testData = {
      menuName: 'Launch',
      menuOptions: '90{f]f9d()',
    };
    const response = await chai.request(app).post('/v1/menus').send(testData);
    expect(response).to.have.status(400);
    expect(response.body).to.be.an('object');
    expect(response.body).to.have.property('message').equal('Fail! Menu options must be letters and seperated by spaces');
  });
});

这是我得到`$ npm test test / setMenu.js

的错误
  

Book-A-Meal@1.0.0测试C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal   摩卡--require @ babel / register --require @ babel / polyfill-退出“ test / setMenu.js”

应用程序正在运行,并且正在端口3000上监听!   在“ / v1 / menus”处测试端点以使用POST设置菜单     √如果所有请求数据均有效(222ms),则应在菜单“ / v1 / menus”处设置菜单     √如果请求中的菜单名称不存在,则不应使用POST在“ / v1 / menus”处创建菜单     √如果请求中的菜单名称为空字符串,则不应使用POST在“ / v1 / menus”处创建菜单     √如果请求中的菜单名称不是字母,则不应使用POST在“ / v1 / menus”处创建菜单 TypeError:无法读取未定义的属性“ split”     在BookAMeal.split上[作为menuFormat](C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ models / index.js:42:41)     在menuFormat(C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ controllers / setMenus.js:7:47)     返回句柄(C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express-promise-router \ lib \ express-promise-router.js:24:27 )     在C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express-promise-router \ lib \ express-promise-router.js:56:9     返回句柄(C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express-promise-router \ lib \ express-promise-router.js:24:27 )     在C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express-promise-router \ lib \ express-promise-router.js:56:9     在Layer.handle上[作为handle_request](C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express \ lib \ router \ layer.js:95:5 )     在下一个(C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express \ lib \ router \ route.js:137:13)     在Route.dispatch(C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express \ lib \ router \ route.js:112:3)     在Layer.handle上[作为handle_request](C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express \ lib \ router \ layer.js:95:5 )     在C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express \ lib \ router \ index.js:281:22     在Function.process_params(C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express \ lib \ router \ index.js:335:12)     在下一个(C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express \ lib \ router \ index.js:275:10)     在Function.handle(C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express \ lib \ router \ index.js:174:3)     在路由器上(C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express \ lib \ router \ index.js:47:12)     在Layer.handle上[作为handle_request](C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express \ lib \ router \ layer.js:95:5 )     在trim_prefix(C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express \ lib \ router \ index.js:317:13)     在C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express \ lib \ router \ index.js:284:7     在Function.process_params(C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express \ lib \ router \ index.js:335:12)     在下一个(C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ express \ lib \ router \ index.js:275:10)     在C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ body-parser \ lib \ read.js:130:5     在invokeCallback(C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ raw-body \ index.js:224:16)     完成时(C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ raw-body \ index.js:213:7)     在IncomingMessage.onEnd(C:\ Users \ okezie \ Desktop \ WEB DEV \ ALCwithForLoop \ Project \ BookAMeal-App \ Book-A-Meal \ node_modules \ raw-body \ index.js:273:7)     在IncomingMessage.emit(events.js:182:13)     在endReadableNT(_stream_visible.js:1094:12)     在process._tickCallback(内部/进程/next_tick.js:63:19)     1)如果请求中的菜单选项不存在,则不应使用POST在“ / v1 / menus”处创建菜单     √如果请求中的菜单选项为空字符串,则不应使用POST在“ / v1 / menus”处创建菜单     √如果请求中的菜单选项不是字母,则不应使用POST在“ / v1 / menus”处创建菜单

6次通过(490ms)   1个失败

1)在“ / v1 / menus”处测试端点以使用POST设置菜单        如果请求中的菜单选项不存在,则不应使用POST在“ / v1 / menus”处创建菜单:

  AssertionError: expected { Object (_events, _eventsCount, ...) } to have status code 400 but got 500
  + expected - actual

  -500
  +400

  at Context.status (test/setMenu.js:70:30)
  at process._tickCallback (internal/process/next_tick.js:68:7)

npm错误!测试失败。有关更多详细信息,请参见上文。 `

到目前为止,我已经尝试了所有我能想到的一切,我愿意根据要求提供更多信息,但我不明白为什么出于某些明显的模糊原因,本质上相同的代码可能有效还是无效?气候错误,要求我拒绝重复代码?为什么看起来Node JS需要重复代码才能正常运行?输入这个问题时,我感到非常沮丧

0 个答案:

没有答案