Nodejs中一个mocha的问题

Nodejs中一个mocha的问题

UserHelper = getTestUser: (callback) -> User.findByUUID “4CD5E71C-EBD3-4E15-8AE3-84570EA340EC”, (err, user) -> User.findByUUID “4c003162-00fa-426f-9542-fe2c26b31f1b”, (err, staff) -> callback user, staff

describe “App”, -> client = null user = null staff = null beforeEach -> server.start client = io.connect socketURL, options UserHelper.getTestUser (userCB,staffCB)-> user = userCB staff = staffCB

afterEach -> server.stop

describe “#hello”, -> it “no callback”, (done) -> client.once “connect”, -> client.emit “hello”, appkey: "083a7ccf484b2e49a8e46d80" uuid: user.uuid

为什么user是null呢?


6 回复

在你提供的代码中,UserHelper.getTestUser 方法的回调函数没有正确地传递参数。此外,UserHelper.getTestUser 的回调函数应该是单个参数的形式,而不是两个独立的参数。这可能是导致 userstaff 变量为 null 的原因。

下面是修改后的代码:

// UserHelper.js
const UserHelper = {
  getTestUser: (callback) => {
    const uuids = [
      "4CD5E71C-EBD3-4E15-8AE3-84570EA340EC",
      "4c003162-00fa-426f-9542-fe2c26b31f1b"
    ];

    const getUser = (uuid, index, callback) => {
      User.findByUUID(uuid, (err, user) => {
        if (err) return callback(err);
        if (index === 1) {
          callback(null, user);
        }
      });
    };

    let count = 0;
    let results = [];

    uuids.forEach((uuid, index) => {
      getUser(uuid, index, (err, user) => {
        if (err) return callback(err);
        results[index] = user;

        if (++count === uuids.length) {
          callback(null, ...results);
        }
      });
    });
  }
};

// mocha测试代码
const server = require('./server'); // 假设你的服务器文件是server.js
const io = require('socket.io-client');
const socketURL = 'http://localhost:3000'; // 假设你的服务器运行在3000端口
const options = {}; // 假设你的连接选项

describe("App", () => {
  let client = null;
  let user = null;
  let staff = null;

  beforeEach(() => {
    server.start();
    client = io.connect(socketURL, options);

    UserHelper.getTestUser((err, userCB, staffCB) => {
      if (err) throw err;
      user = userCB;
      staff = staffCB;
    });
  });

  afterEach(() => {
    server.stop();
  });

  describe("#hello", () => {
    it("no callback", (done) => {
      client.on("connect", () => {
        client.emit("hello", {
          appkey: "083a7ccf484b2e49a8e46d80",
          uuid: user.uuid
        });
        done(); // 确保异步操作完成后调用done
      });
    });
  });
});

解释

  1. UserHelper.getTestUser: 修改了该方法以确保正确地获取用户信息并传递给回调函数。
  2. beforeEach: 在每次测试前启动服务器并连接客户端。同时,通过 UserHelper.getTestUser 获取用户信息。
  3. done: 在测试完成后调用 done 函数以确保测试框架知道异步操作已完成。

这样可以确保 userstaff 能够被正确赋值,并且不会为 null


getTestUser(callback)只有一个参数(回调函数),为什么如此调用:getTestUser (userCB,staffCB)

那怎么修改

UserHelper.getTestUser是一个异步函数,所以beforeEach的回调函数也要使用异步的形式:

  beforeEach (done) ->
    server.start
    client = io.connect socketURL, options
    UserHelper.getTestUser (userCB,staffCB)->
      user = userCB
      staff = staffCB
      done()

另外node.js约定callback形式的异步函数,传给回调函数的第一个参数是error对象,所以你第四行callback user, staff这样的代码是不符合约定的,当和async之类的类库一起用的时候很容易出问题。

但我加了done后,就2000MS的错误了

从你提供的代码来看,UserHelper.getTestUser 函数使用了异步回调,但在 beforeEach 钩子中,你没有正确处理这些回调。这可能导致 userstaff 变量在你需要它们之前还没有被赋值。

示例代码修正

const UserHelper = {
    getTestUser: (callback) => {
        User.findByUUID("4CD5E71C-EBD3-4E15-8AE3-84570EA340EC", (err, user) => {
            if (err) return callback(err);
            User.findByUUID("4c003162-00fa-426f-9542-fe2c26b31f1b", (err, staff) => {
                if (err) return callback(err);
                callback(null, user, staff);
            });
        });
    }
};

describe('App', () => {
    let client = null;
    let user = null;
    let staff = null;

    beforeEach((done) => { // 注意这里添加了 done 参数
        server.start();
        client = io.connect(socketURL, options);
        UserHelper.getTestUser((err, userCB, staffCB) => { // 直接传递 err 和结果
            if (err) throw err; // 处理错误
            user = userCB;
            staff = staffCB;
            done(); // 确保完成回调被执行
        });
    });

    afterEach(() => {
        server.stop();
    });

    describe('#hello', () => {
        it('no callback', (done) => {
            client.on('connect', () => {
                client.emit('hello', {
                    appkey: "083a7ccf484b2e49a8e46d80",
                    uuid: user.uuid
                });
                // 可以在这里添加断言或其他逻辑
                done(); // 测试完成
            });
        });
    });
});

解释

  1. beforeEach 钩子: 添加了 done 参数来确保异步操作完成后执行。
  2. UserHelper.getTestUser: 使用 callback 来传递错误和结果,并确保在所有操作完成后调用 done()
  3. 错误处理: 在 getTestUser 回调中增加错误处理,确保如果出现错误能够及时抛出。

通过这种方式,可以确保在进入测试用例之前,userstaff 已经被正确赋值。

回到顶部