在 jestjs 中完成测试后无法登录

Posted

技术标签:

【中文标题】在 jestjs 中完成测试后无法登录【英文标题】:Cannot log after tests are done in jestjs 【发布时间】:2019-07-29 01:05:54 【问题描述】:

我已经使用 jest 为登录 API 编写了测试用例。完成测试服的所有五项测试后,请在日志中给我以下错误。

任何人都可以说出为什么会这样以及如何解决它吗?

代码:(signup.test.ts)

import request from 'supertest';
import  TYPES  from '../src/inversify.types'
import  Application  from '../src/app/Application'
import  container  from '../src/inversify.config'
import dotenv from 'dotenv'
import  RESPONSE_CODE  from '../src/utils/enums/ResponseCode'
import  RESPONSE_MESSAGES  from '../src/utils/enums/ResponseMessages'
import  UserSchema  from '../src/components/user/User';
// import jwt from 'jsonwebtoken';
var application: Application

describe("POST / - SIGNUP endpoint", () => 
    // var testusers: any;
    //This hook is executed before running all test cases, It will make application instance, make it to listen 
    // on it on port 3000 and add test document in DB
    beforeAll(async () => 
        // Make enviroment variables available throughout the application
        dotenv.config();
        // Getting application instance using iversify container
        application = container.get<Application>(TYPES.Application);
        // Initialize frontside of application
        await application.bootstrap();
        // Starting Application server on given port
        await application.listen(3000);
    );

    afterAll(
        //This hook is executed after running all test cases and delete test document in database
        async () =>
        const res = await UserSchema.deleteMany( Name:  $in: [ "Test User", "Test" ]  );
        // `0` if no docs matched the filter, number of docs deleted otherwise
        console.log('---------------------->>>>>>>>>>>>>>>>>>>', (res as any).deletedCount);
    
    )

    it("Signup for user that don\'t exists", async () => 
        const response = await request(application.getServer()).post('/user/signup')
        .send(
            "Email": JSON.parse(process.env.TEST_USER).Email,
            "Name": "Test User",
            "Password": process.env.TEST_ACCOUNTS_PASSWORD
            )
            expect(response.status).toBe(RESPONSE_CODE.CREATED);
            expect(JSON.parse(response.text)).toEqual(expect.objectContaining( 
                Message: RESPONSE_MESSAGES.ADDED_SUCESSFULLY, 
                Data: expect.objectContaining(
                    Name: 'Test User',
                    Country: '',
                    PhoneNumber: '',
                    // Password: '$2b$10$nIHLW/SA73XLHoIcND27iuODFAArOvpch6FL/eikKT78qbShAl6ry',
                    Dob: '',
                    Role: 'MEMBER',
                    IsEmailVerified: false,
                    IsBlocked: 'ACTIVE',
                    IsTokenSent: false,
                    twoFAStatus: false,
                    // _id: '5c812e2715e0711b98260fee',
                    Email: JSON.parse(process.env.TEST_USER).Email
                )
            )
            );
        console.log('*** Signup for user that don\'t exists *** response', response.text, 'response status', response.status);   
    );
    it("Signup for user that exists", async () => 
        const response = await request(application.getServer()).post('/user/signup')
        .send(
            "Email": JSON.parse(process.env.TEST_USER).Email,
            "Name": "Test User",
            "Password": process.env.TEST_ACCOUNTS_PASSWORD
            )
            expect(response.status).toBe(RESPONSE_CODE.CONFLICT);
            expect(JSON.parse(response.text)).toEqual( 
                Message: RESPONSE_MESSAGES.ALREADY_EXISTS
            )
        console.log('*** Signup for user that don\'t exists *** response', response.text, 'response status', response.status);   
    );

);

Jest 在测试运行完成后一秒没有退出。

这通常意味着存在未执行的异步操作 在您的测试中停止。考虑运行 Jest --detectOpenHandles 解决此问题。

测试完成后无法登录。你是否忘记等待某事 在你的测试中异步?

Attempted to log " accepted: [ 'unverifiedtestuser@abc.com' ],
      rejected: [],
      envelopeTime: 621,
      messageTime: 867,
      messageSize: 906,
      response: '250 2.0.0 OK  1551945300 f6sm5442066wrt.87 - gsmtp',
      envelope:
        from: 'abc@gmail.com',
         to: [ 'unverifiedtestuser@abc.com' ] ,
      messageId: '<45468449-b5c8-0d86-9404-d55bb5f4g6a3@gmail.com>' ".




at CustomConsole.log (node_modules/jest-util/build/CustomConsole.js:156:10)
  at src/email/MailHandler.ts:2599:17
  at transporter.send.args (node_modules/nodemailer/lib/mailer/index.js:226:21)
  at connection.send (node_modules/nodemailer/lib/smtp-transport/index.js:247:32)
  at callback (node_modules/nodemailer/lib/smtp-connection/index.js:435:13)
  at stream._createSendStream (node_modules/nodemailer/lib/smtp-connection/index.js:458:24)
  at SMTPConnection._actionSMTPStream (node_modules/nodemailer/lib/smtp-connection/index.js:1481:20)
  at SMTPConnection._responseActions.push.str (node_modules/nodemailer/lib/smtp-connection/index.js:968:22)
  at SMTPConnection._processResponse (node_modules/nodemailer/lib/smtp-connection/index.js:764:20)
  at SMTPConnection._onData (node_modules/nodemailer/lib/smtp-connection/index.js:570:14)

【问题讨论】:

你能发布测试本身的代码吗?这将有助于诊断正在发生的事情。这是Jest async example 和example GitHub issue,让您了解可能导致此类错误的情况。 @ty2k。我已经更新了代码请检查。我已经签出文档但无法弄清楚 查看 Jest 的异步文档中的 Callbacks 部分,特别是将 done 作为参数传递的部分。还有这个post in a Supertest issue 和你有同样的问题。基本上,你的测试在你的服务器关闭之前就已经完成了。 【参考方案1】:

如果您在代码中使用 async/await 类型,那么当您在没有 await 关键字的情况下调用 async 函数时可能会出现此错误。

就我而言,我在下面定义了一个这样的函数,

async getStatistics(headers) 
    ....
    ....
    return response;

但我将这个方法称为getStatistics(headers) 而不是await getStatistics(headers)

当我添加await 时,它运行良好并且问题解决了。

【讨论】:

【参考方案2】:

Cannot log after tests are done 发生时,我正在使用 react-native 默认测试用例(见下文)。

it('renders correctly', () => 
  renderer.create(<App />);
);

显然,问题在于测试结束但仍需要记录。所以我尝试使测试用例中的回调异步,希望测试不会立即终止:

it('renders correctly', async () => 
  renderer.create(<App />);
);

它奏效了。但是,我几乎不知道内部工作是什么。

【讨论】:

很遗憾对我不起作用!注意:在 App.js 中,我只渲染导航组件 Config "NavigationContainer"【参考方案3】:

我也有类似的问题:

Cannot log after tests are done. Did you forget to wait for something async in your test?
Attempted to log "Warning: You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. ".

这是由于缺少 static 关键字。此代码导致了问题:

class MyComponent extends React.Component<Props, State> 
  propTypes = 
    onDestroy: PropTypes.func,
  

应该是:

class MyComponent extends React.Component<Props, State> 
  static propTypes = 
    onDestroy: PropTypes.func,
  

【讨论】:

【参考方案4】:

在我的情况下,错误是由异步 Redis 连接仍然在线引起的。刚刚添加了 afterall 方法来退出 Redis 并且可以再次看到日志。

使用 Typescript 4.4.2:

test("My Test", done => 
    let redisUtil: RedisUtil = new RedisUtil();
    let redisClient: Redis = redisUtil.redis_client();
    done();
);

afterAll(() => 
    redisClient.quit();
);

【讨论】:

【参考方案5】:

对我来说,我需要在 expect() 调用之前添加一个 await 以停止此错误(以及在 test() 回调函数之前添加一个 async)。

还导致并修复了 Jest 未检测到代码中引发错误的行的覆盖率!

test("expect error to be thrown for incorrect request", async () => 
  await expect(
  // ^ added this
    async () => await getData("i-made-this-up")
  ).rejects.toThrow(
    "[API] Not recognised: i-made-this-up"
  );
);

getData() 返回一个 Axios 调用,在这种情况下,catch 捕捉到错误并重新抛出。

const getData = async (id) => 
  return await axios
    .get(`https://api.com/some/path?id=$id`)
    .then((response) => response.data)
    .catch((error) => 
      if (error?.response?.data?.message) 
        console.error(error) // Triggered the error
        throw new Error("[API] " + error.response.data.message);
      

      throw error;
    );
;

【讨论】:

以上是关于在 jestjs 中完成测试后无法登录的主要内容,如果未能解决你的问题,请参考以下文章

针对需要登录的接口如何做性能测试?

成功登录后无法关闭 UIViewController

在 Visual Studio 中部署应用程序后,Xbox 登录无法正常工作

笔记本电脑开机时,输入密码登录,无法登录到桌面,显示:由于远程桌面服务当前正忙,无法完成您尝试执行

“由于远程桌面服务正忙,因此无法完成你尝试执行的任务,请在几分钟后重试,其他用户应该任然能够登录,

启用系统防火墙后无法登录 xmpp 聊天服务器