首页 > 解决方案 > 如何使用 jest 在课堂上测试功能

问题描述

我无法使用 jest 进行单元测试

我正在尝试测试一个特定的函数,该函数正在调用或期待其他函数的结果,但我不确定它为什么不起作用。我对单元测试很陌生,真的不知道如何让它工作。目前这是我尝试过的

export class OrganizationService {

    constructor() {
        this.OrganizationRepo = new OrganizationRepository()
    }

    async getOrganizations(req) {
        if (req.permission !== 'internal' && req.isAuthInternal === false) {
            throw new Error('Unauthenticated')
        }
        const opt = { deleted: true }
        return this.OrganizationRepo.listAll(opt)
    }

}

这是我扩展 MongoDbRepo 的 OrganizationRepository

import { MongoDbRepo } from './mongodb_repository'

export class OrganizationRepository extends MongoDbRepo {

    constructor(collection = 'organizations') {
        super(collection)
    }

}

这是 MongoDbRepo

const mongoClient = require('../config/mongo_db_connection')
const mongoDb = require('mongodb')

export class MongoDbRepo {

    constructor(collectionName) {
        this.collection = mongoClient.get().collection(collectionName)
    }

    listAll(opt) {

        return new Promise((resolve, reject) => {
            this.collection.find(opt).toArray((err, data) => {
                if (err) {
                    reject(err)
                }
                resolve(data)
            })
        })
    }
}

这是我所做的测试

import { OrganizationService } from '../../../src/services/organization_service'

describe('getOrganizations', () => {
    it('should return the list of organizations', () => {
        // const OrgRepo = new OrganizationRepository()
        const orgService = new OrganizationService()

        const OrgRepo = jest.fn().mockReturnValue("[{_id: '123', name: 'testname'}, {_id: '456, name: 'testname2'}]")
        // orgService.getOrganizations = jest.fn().mockReturnValue('')
        const result = orgService.getOrganizations()

        expect(result).toBe(OrgRepo)
    })
})

标签: node.jsjestjs

解决方案


我在您的测试方式中发现了两个问题:

1.

expect您正在尝试测试一个异步方法,并且在您的测试中,您不会在您的语句之前等待此方法完成。

一个好的测试结构应该是:

it('should test your method', (done) => {
    const orgService = new OrganizationService();

    const OrgRepo = jest.fn().mockReturnValue("[{_id: '123', name: 'testname'}, {_id: '456, name: 'testname2'}]")
    orgService.getOrganizations()
    .then((result) => {
        expect(result).toEqual(OrgRepo); // I recommend using "toEqual" when comparing arrays
        done();
    });
})

不要忘记将done其作为测试参数!

您可以在Jest 官方文档中找到更多关于测试异步函数的信息。

2.

为了正确测试您的方法,您希望其与外部依赖项隔离开来。OrganizationRepo.listAll()这里调用了实际的方法。您想模拟此方法,例如使用间谍,以便您控制其结果并仅测试该getOrganizations方法。看起来像这样:

it('should test your method', (done) => {
    const req = {
      // Whatever structure it needs to be sure that the error in your method is not thrown
    };
    const orgService = new OrganizationService();
    const orgRepoMock = spyOn(orgService['OrganizationRepo'], 'listAll')
    .and.returnValue(Promise.resolve("[{_id: '123', name: 'testname'}, {_id: '456, name: 'testname2'}]"));

    const OrgRepo = jest.fn().mockReturnValue("[{_id: '123', name: 'testname'}, {_id: '456, name: 'testname2'}]");
    orgService.getOrganizations(req)
    .then((result) => {
        expect(result).toEqual(OrgRepo); // I recommend using "toEqual" when comparing arrays
        expect(orgRepoMock).toHaveBeenCalled(); // For good measure
        done();
    });
})

这样,我们确保您的方法是孤立的,并且其结果不能被外部方法改变。

对于这种特定的方法,我还建议您根据方法的输入来测试抛出的错误。


推荐阅读