在Jest中测试嵌套的promise

时间:2018-04-25 17:45:47

标签: javascript unit-testing promise async-await jest

我在Jest中测试以下功能时遇到问题。我有一个函数,可以将数组或promise作为参数。无论哪种方式,我将该参数传递给axios调用,唯一的区别是如果参数是一个promise,我会在将.then()传递给调用之前调用sendItems.js

这一切都很好,花花公子,但我在编写单元测试时遇到了麻烦,以确认这是有效的。

import axios from 'axios' export const saveItems = () => { return axios({ url: '/stuff/graphql', method: 'post', credentials: 'same-origin', data: { whatever: 'yo' } }) .then(response => { return response }) .catch(err => { return err }) } export const sendItems = items => { if(items instanceof Promise){ items.then(result => { return saveItems(result) }) .catch(err => { return err }) } else{ return saveItems(items) } } export default { sendItems, saveItems }

/* global jest, describe, beforeAll, beforeEach, expect, test */
import axios from 'axios'
import MockAdapter from 'axios-mock-adapter'

describe('save items', () => {
  let sendItems, mock, items

  beforeAll(() => {
    sendItems = require('../services/sendItems.js').sendItems
    mock = new MockAdapter(axios)
    items = [
      {
        pid: '1',
        name: 'shoe'
      }
    ]
  })

  test('returns 200 when the call to save items is successful', async () => {
    const response = {
      status: 200,
      data: 'success'
    }
    mock.onPost('stuff/graphql').reply(200, response)
    const sendItemsResp = await sendItems(items)
    expect(sendItemsResp.data.status).toEqual(response.status)
  })

  test('correctly resolves the value of input passed to the service, if it is a Promise', async() => {
    const response = {
      status: 200,
      data: 'success'
    }

    items = Promise.resolve([{"p": 1}, {"p": 2}])

    mock.onPost('stuff/graphql').reply(200, response)

    const sendItemsResp = await sendItems(items)
    expect(sendItemsResp.response.status).toEqual(response.status)
    // expect(saveItems).toHaveBeenCalledWith([{"p": 1}, {"p": 2}])
  })
})

测试看起来像这样:

sendItems

我将数组传递给sendItems的早期测试通过​​,但是由于sendItemsResp未定义的事实,我将Promise传递给console.log(saveItems(result)的后一个测试失败了。如果我在运行后一个测试时在sendItems函数中放置 import sqlite3 conn = sqlite3.connect('emaildb.sqlite') cur = conn.cursor() cur.execute('DROP TABLE IF EXISTS Counts') cur.execute('''CREATE TABLE Counts (email TEXT, count INTEGER)''') fname = input('Enter file name: ') fh = open(fname) for line in fh: if not line.startswith("From"): continue pieces = line.split() email = pieces[1] cur.execute('SELECT count FROM Counts WHERE email= ? ', (email,)) row = cur.fetchone() if row is None: cur.execute('''INSERT INTO Counts (email, count) VALUES (?, 1)''', (email,)) else: cur.execute('UPDATE Counts SET count = count + 1 WHERE email= ?',(email,)) cur.execute('SELECT * FROM Counts ORDER BY count DESC') conn.commit() ,我会得到一个待处理的承诺,所以我假设我需要一些如何在此测试中解决该承诺。但是,我不知道该怎么做。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:3)

class SomePage extends StatefulWidget { @override _SomePageState createState() => new _SomePageState(); } class _SomePageState extends State<SomePage> { String _userName = "..."; _getUserAuth(){ FirebaseAuth.instance.currentUser().then((user){ setState((){this._userName= user.displayName;}); }); print(this._userName); } @override Widget build(BuildContext context) { return new Center( child: new FlatButton( child: new Text(this._userName), onPressed: _getUserAuth, ), ); } }

中缺少return声明

此外,您可以items.then(result => {

const sendItems = items => Promise.resolve(items).then(saveItems).then也是多余的。