【发布时间】:2018-11-29 13:13:01
【问题描述】:
问题
在单元测试中创建新的类实例不会触发构造函数。
详情
我正在尝试测试在给定错误的服务器 IP 时是否引发错误,但是当我尝试创建应该引发错误的类的新实例时它不起作用。
我要测试的课程是:
export class ClassA {
private readonly _redisServerIP = config.redisServerIP;
private readonly _redisServerPort = config.redisServerPort;
constructor() {
console.log(this._redisServerIP);
this.configure();
}
private configure(): void {
this._redisSub = redis.createClient({host: this._redisServerIP, port: this._redisServerPort});
this._redisSub.on('error', (error) => {
if (error.code === "ECONNREFUSED") {
this._logger.error('Could not create a redisSub, is the redis server running?');
}
throw new Error('Something bad happened');
});
}
}
这是我的测试代码:
import * as constants from '../src/config/config';
let socket;
let classA;
let httpServerAddr;
beforeAll((done) => {
classA = new ClassA();
httpServerAddr = classA.getServerIp();
done();
});
afterAll((done) => {
done();
});
beforeEach((done) => {
});
afterEach((done) => {
done();
});
describe('Socket.io redis testing', () => {
test('should fail due to invalid serverIP', () => {
constants.config.redisServerIP = "0.0.0.0";
classA = null;
expect(() => {
classA = new ClassA();
}).toThrow();
});
});
我在节点控制台中只看到一次服务器 ip,由于以下错误,测试失败:
expect(function).toThrow(undefined)
Expected the function to throw an error.
But it didn't throw anything.
这是因为每个测试都按照自己的承诺运行吗?当它在那个承诺中运行时,它不能登录到控制台?还是因为我在调用 new ClassA() 之前没有清除 ClassA 的现有实例?
======编辑======
使用断点后,我发现调用了构造函数,但它并没有写入控制台。但是抛出永远不会发生,redis 是如何工作的;如果它有一个错误,一个名为“error”的事件被发送到redis服务器,运行测试时不会触发,如何等待触发?
【问题讨论】:
-
它是异步的;调用 new 不会导致异常,最终的回调会。
-
有道理,如何进行测试?我尝试使我的测试异步并在我期望的前面添加了等待,但它仍然没有触发。
-
await什么都没有;任何地方都不涉及任何承诺。您可以使类实例化同步(在这种情况下这很有意义,具体取决于您实际想要如何使用它,因为如果没有可用的 Redis 实例,则需要处理它)。所以你可以简单地将事件包装在 Promise 中,在 ctor 中等待,问题就解决了。 -
是不是有点脏?可悲的是,没有其他方法可以检测 redis 连接是否失败,但是将它包装在 promise 周围,然后在我的构造函数中等待肯定不是解决这个问题的唯一方法吗?
-
当然不是。从应用程序的角度来看,它可能是最有意义的,但这并不意味着你必须这样做——你已经有一个竞争条件,你无法知道 Redis 连接是否已经在您可以使用课程之前成功完成,所以如果您不在乎,没有理由等待。您可以通过等待时间、随时间轮询等方式,以与您在应用程序中处理它的方式完全相同的方式处理它。就我个人而言,我会将其包装在您自己的事件或承诺中,这样您就不必只是猜,但是 YMMV。
标签: typescript unit-testing testing jestjs node-redis