如何在单元测试中解决异步等待 - javascript

时间:2017-09-20 12:03:54

标签: javascript unit-testing lambda

我有一个lambda,我想为它编写单元测试。我正在使用异步等待,但我遇到了解决承诺的问题。我想测试不同的条件,如何编写测试来解决并停止查看超时?

提前致谢。

  

错误:超出2000毫秒超时。对于异步测试和挂钩,请确保   "()完成"叫做;如果返回Promise,请确保它已解决。

---单位

describe('tests', function() {

    describe('describe an error', () => {
        it('should return a 500', (done) => {
            handler('', {}, (err, response) => {
                expect(err.status).to.eq('failed')
                done()
            })
        })
    })

});

- 处理程序

export const handler = async (event, context, callback) => { 

 return callback(null, status: 500 )

})

4 个答案:

答案 0 :(得分:7)

请尝试以下操作:

import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.media.multipart.*;
import org.glassfish.jersey.media.multipart.file.FileDataBodyPart;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import java.io.*;
import java.util.logging.Logger;

import static org.junit.Assert.assertEquals;

public class MutliPartMixedTest extends JerseyTest {

    @Path("test")
    public static class TestResource {

        @POST
        @Consumes("multipart/mixed")
        @Produces("text/plain")
        public String post(MultiPart multiPart) throws Exception {
            BodyPart part = multiPart.getBodyParts().get(0);
            return part.getEntityAs(String.class);
        }
    }

    @Override
    public ResourceConfig configure() {
        return new ResourceConfig()
                .register(TestResource.class)
                .register(MultiPartFeature.class)
                .register(new LoggingFilter(Logger.getAnonymousLogger(), true))
                .register(new ExceptionMapper<Throwable>() {
                    @Override
                    public Response toResponse(Throwable t) {
                        t.printStackTrace();
                        return Response
                                .serverError()
                                .entity(t.getMessage())
                                .build();
                    }
                });
    }

    @Test
    public void doIt() throws Exception {
        File file = new File("test.txt");
        try (Writer writer = new BufferedWriter(new FileWriter(file))) {
            writer.write("Hello World!");
        }
        FileDataBodyPart filePart = new FileDataBodyPart("data", file);
        MultiPart multiPart = new MultiPart()
                .bodyPart(filePart);

        try {
            Response response = ClientBuilder.newClient()
                    .register(MultiPartFeature.class)
                    .target("http://localhost:9998/test")
                    .request()
                    .accept("text/plain")
                    .post(Entity.entity(multiPart, "multipart/mixed"));

          assertEquals("Hello World!", response.readEntity(String.class));
        } finally {
            file.delete();
        }
    }
}

describe('tests', function() {
    describe('describe an error', () => {
        it('should return a 500', (done) => {
            await handler('', {}, (err, response) => {
                expect(err.status).to.eq('failed');
            })
            done();
        })
    })
});

无论如何,我想,你需要describe('tests', function() { describe('describe an error', () => { it('should return a 500', async () => { const error = await handler('', {}, (err, response) => Promise.resolve(err)) expect(error.status).to.eq('failed'); }) }) }); 你的异步处理程序......

答案 1 :(得分:3)

您可以增加测试的超时时间。

describe('tests', function() {

    describe('describe an error', () => {
        it('should return a 500', (done) => {
            handler('', {}, (err, response) => {
                expect(err.status).to.eq('failed')
                done()
            })
        }).timeout(5000)
    })

});

timeout方法接受以毫秒为单位的时间。默认值为2000

答案 2 :(得分:3)

根据您使用的框架,有多种方法可以处理async单元测试。

例如,如果您正在使用Jasmine

1)您可以使用Spyasync回调替换为静态函数,这样就不会asyncronous,您可以模拟返回数据。这对于您不需要测试动态异步操作的单元测试非常有用(与集成测试不同)。

2)还可以在此处找到真正的异步支持文档:Asynchronous Support

3)您应该始终使用beforeEach()进行async测试作为您在描述级别定义done()功能的地方

答案 3 :(得分:1)

使用Blue Tape。它是Tape的一个薄包装,是Eric Elliott等推荐的一个简单,高效的测试框架。

Blue Tape处理任何自动返回promise的测试。

使用async / await的所有方法都会根据ECMAScript规范返回promise。

这是它的样子

import test from 'blue-tape';

test('`functionThatReturnsAPromise` must return a status of "failed"', async ({equals}) => {
  const {result} = await functionThatReturnsAPromise();
  equals(status, 'failed');
});

如果只包含async关键字,您甚至可以通过这种方式编写同步测试。

请注意在大多数框架中,如何使用doneend或与异步测试相关的任何其他样板和噪声。

我强烈建议你试一试。