Async Jasmine测试在操作之前不会调用beforeEach()

时间:2018-04-14 17:07:10

标签: javascript node.js asynchronous testing jasmine

我试图将测试编码到我的客户端 - 服务器模块。我需要在客户端发送请求之前运行服务器,因此我尝试使用beforeEach,但测试在服务器开始运行之前就失败了。

我的测试:

'use strict';
const cp    = require('child_process');
const ip    = require('my-local-ip');
const utils = require('../util/utils');

describe('Server and client connectivity:', () => {

    let originalTimeout;
    let server;

    beforeEach(function() {
        server = cp.fork('Server/Server');
        originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
        jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
    });

    it('should transfer index.html file to client', (done) => {
        const client = cp.fork('Client/request', ['-t', ip(), '-p', 3300]);
        expect(utils.isFileExistsInDirectory('Client/', 'index.html')).toBe(true);
        done();
    });

    afterEach(function() {
        jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
    });

});

当我首先手动运行服务器,然后使用这些命令运行客户端时,它运行正常。

在测试中,有时客户端请求在服务器正在侦听之前发送
怎么会发生?
我做错了什么?

1 个答案:

答案 0 :(得分:0)

在当前的实施中,您要求服务器进程分叉,但等待服务器实际启动。

要解决这个问题,我们需要建立一些进程间通信。 如果使用fork,使用.send.on很容易做到,因为:

  

返回的ChildProcess将进行额外的通信   内置的通道,允许消息来回传递   父母和孩子之间...

根据the doc

请参阅示例server.js



// A simple server
const express = require('express');

const app = express();
app.get('/', (req, res) => res.json({message: 'ok'}));

app.listen(8080, () => {
	// This function exists only if this is a child process
	if (process.send) {
		// Telling the parent that the server is launched
		process.send('launched');
	}

	console.log('Server started');
});




spec.js



const child_process = require('child_process');
const request = require('request');
const assert = require('assert');

describe('Connectivity with forked server', () => {
	let server;

	beforeAll(done => {
		server = child_process.fork('server.js');

		// Wait for the message from a child server before running any tests
		server.on('message', data => {
			if (data === 'launched') {
				console.log('Before block executed');
				done();
			}
		});
	});

	// Killing the server after all the tests
	afterAll(() => server.kill('SIGTERM'));

	it('should be able to interact with server', done => {
		request({url: 'http://localhost:8080', json: true}, (err, resp, body) => {
			if (err) {
				return done(err);
			}

			assert.equal(body.message, 'ok');

			console.log('test executed');
			done();
		});
	});
});




我已使用beforeAllafterAll代替beforeEach,但如果需要,您可以切换回beforeEach

另外,我已经设置了一些逻辑来在执行测试后关闭进程。