Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/438.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jest:如何使用MongoDB正确测试Javascript服务_Javascript_Mongodb_Testing_Jestjs - Fatal编程技术网

Jest:如何使用MongoDB正确测试Javascript服务

Jest:如何使用MongoDB正确测试Javascript服务,javascript,mongodb,testing,jestjs,Javascript,Mongodb,Testing,Jestjs,我完全不懂开玩笑 我有一个使用依赖注入的UserService public async getAll() { const userRecords = await this.userModel.find().select('name').catch((e) => { throw new HttpException(500, 'Error while fetching users.', e) }); return <[IUser]>userRecords; }

我完全不懂开玩笑

我有一个使用依赖注入的
UserService

public async getAll() {
  const userRecords = await this.userModel.find().select('name').catch((e) => {
    throw new HttpException(500, 'Error while fetching users.', e)
  });
  return <[IUser]>userRecords;
}
但显然它失败了,因为
select未定义


我是否也应该模拟
select()
?我是否应该以不同的方式组织代码?

如果要编写此测试,我将模拟使用的函数,以便在函数调用上实现期望

const userQuery = {
    select: jest.fn(() => Promise.resolve([]))
};

const userModel = {
    find: jest.fn(() => userQuery)
};

const userService = new UserService(userModel);
const userRecords = await userService.getAll();

expect(userRecords).toEqual([]);
expect(userModel.find).toHaveBeenCalled();
expect(userQuery.select).toHaveBeenCalledWith('name');
对函数调用执行期望可能听起来有些过分,但它明确地验证了
getAll
实际正在使用mock

我还将以这样一种方式构建测试,即我可以测试各种代码路径,而无需重新实现整个模拟

describe('getAll()', () => {

    let userQuery, userModel, userService;
    beforeEach(() => {
        userQuery = {
            select: jest.fn(() => Promise.resolve([]))
        };

        userModel = {
            find: jest.fn(() => userQuery)
        };

        userService = new UserService(userModel);
    });

    afterEach(() => {
        expect(userModel.find).toHaveBeenCalled();
        expect(userQuery.select).toHaveBeenCalledWith('name');
    });

    it('should get the user names', async () => {
        const users = [{
            name: 'john'
        }, {
            name: 'jane'
        }];
        userQuery.select.mockImplementation(() => Promise.resolve(users));

        await expect(userService.getAll()).resolves.toBe(users);
    });

    it('should handle errors', async () => {
        const error = new Error('Fake model error');
        userQuery.select.mockImplementation(() => Promise.reject(error));

        await expect(userService.getAll()).rejects.toMatch({
            status: 500,
            message: 'Error while fetching users.',
            cause: error
        });
    });
});
这段代码未经测试,因此可能无法正常工作,但希望它能充分概括这一想法


虽然这与您的问题没有直接关系,但我会避免将
async/await
与传统的承诺处理混为一谈

public async getAll() {
    try {
        return <[IUser]> await this.userModel.find().select('name');
    } catch (e) {
        throw new HttpException(500, 'Error while fetching users.', e)
    }
}
public async getAll(){
试一试{
return wait this.userModel.find().select('name');
}捕获(e){
抛出新的HttpException(500,“获取用户时出错”。,e)
}
}

如果要编写此测试,我将模拟使用的函数,以便在函数调用上实现预期

const userQuery = {
    select: jest.fn(() => Promise.resolve([]))
};

const userModel = {
    find: jest.fn(() => userQuery)
};

const userService = new UserService(userModel);
const userRecords = await userService.getAll();

expect(userRecords).toEqual([]);
expect(userModel.find).toHaveBeenCalled();
expect(userQuery.select).toHaveBeenCalledWith('name');
对函数调用执行期望可能听起来有些过分,但它明确地验证了
getAll
实际正在使用mock

我还将以这样一种方式构建测试,即我可以测试各种代码路径,而无需重新实现整个模拟

describe('getAll()', () => {

    let userQuery, userModel, userService;
    beforeEach(() => {
        userQuery = {
            select: jest.fn(() => Promise.resolve([]))
        };

        userModel = {
            find: jest.fn(() => userQuery)
        };

        userService = new UserService(userModel);
    });

    afterEach(() => {
        expect(userModel.find).toHaveBeenCalled();
        expect(userQuery.select).toHaveBeenCalledWith('name');
    });

    it('should get the user names', async () => {
        const users = [{
            name: 'john'
        }, {
            name: 'jane'
        }];
        userQuery.select.mockImplementation(() => Promise.resolve(users));

        await expect(userService.getAll()).resolves.toBe(users);
    });

    it('should handle errors', async () => {
        const error = new Error('Fake model error');
        userQuery.select.mockImplementation(() => Promise.reject(error));

        await expect(userService.getAll()).rejects.toMatch({
            status: 500,
            message: 'Error while fetching users.',
            cause: error
        });
    });
});
这段代码未经测试,因此可能无法正常工作,但希望它能充分概括这一想法


虽然这与您的问题没有直接关系,但我会避免将
async/await
与传统的承诺处理混为一谈

public async getAll() {
    try {
        return <[IUser]> await this.userModel.find().select('name');
    } catch (e) {
        throw new HttpException(500, 'Error while fetching users.', e)
    }
}
public async getAll(){
试一试{
return wait this.userModel.find().select('name');
}捕获(e){
抛出新的HttpException(500,“获取用户时出错”。,e)
}
}

是的,您应该模拟
选择
。不仅如此,还包括函数内部使用的所有内容,并测试它们是否正确执行。我会这样做:

class SomeClass {
    public async getAll() {
      const userRecords = await this.userModel.find().select('name').catch(this.errorHandler);

      return <[IUser]>userRecords;
    }

    public errorHandler(e) {
        throw new HttpException(500, 'Error while fetching users.', e);
    }
}

// this is just an example, it should be the same type as your expected returned output
const whatever = Math.random();

const fakeCatch = jest.fn(() => whatever);

const fakeSelect = jest.fn(() => {
    return {
        catch: fakeCatch
    }
});
const fakeFind = jest.fn(() => {
    return {
        select: fakeSelect
    };
});
const fakeUserModel = {
    find: fakeFind,
}

const userService = new UserService(fakeUserModel);
const userRecords = await userService.getAll();

// should return the correct result
expect(userRecords).toEqual(whatever);

// should execute find
expect(fakeFind).toHaveBeenCalledTimes(1);

// should execute select with 'name' parameter
expect(fakeSelect).toHaveBeenCalledTimes(1);
expect(fakeSelect).toHaveBeenCalledWith('name');

// should execute catch with this.errorHandler
expect(fakeCatch).toHaveBeenCalledWith(userService.errorHandler);
class-SomeClass{
公共异步getAll(){
const userRecords=wait this.userModel.find().select('name').catch(this.errorHandler);
返回用户记录;
}
公共错误处理程序(e){
抛出新的HttpException(500,“获取用户时出错”,e);
}
}
//这只是一个示例,它应该与预期返回的输出类型相同
const whatever=Math.random();
const fakeCatch=jest.fn(()=>随便什么);
const fakeSelect=jest.fn(()=>{
返回{
捕获:伪造捕获
}
});
const fakeFind=jest.fn(()=>{
返回{
选择:fakeSelect
};
});
常量fakeUserModel={
查找:伪造查找,
}
const userService=新的userService(fakeUserModel);
const userRecords=await userService.getAll();
//应该返回正确的结果
expect(用户记录)。toEqual(无论什么);
//应该执行find
期望(伪造发现)。被催缴的时间(1);
//应使用“名称”参数执行select
期望(fakeSelect)。已被催缴时间(1);
期望(fakeSelect)。与('name')一起被调用;
//应该使用this.errorHandler执行catch
expect(fakeCatch).tohavencalledwith(userService.errorHandler);

是的,您应该模拟
选择
。不仅如此,还包括函数内部使用的所有内容,并测试它们是否正确执行。我会这样做:

class SomeClass {
    public async getAll() {
      const userRecords = await this.userModel.find().select('name').catch(this.errorHandler);

      return <[IUser]>userRecords;
    }

    public errorHandler(e) {
        throw new HttpException(500, 'Error while fetching users.', e);
    }
}

// this is just an example, it should be the same type as your expected returned output
const whatever = Math.random();

const fakeCatch = jest.fn(() => whatever);

const fakeSelect = jest.fn(() => {
    return {
        catch: fakeCatch
    }
});
const fakeFind = jest.fn(() => {
    return {
        select: fakeSelect
    };
});
const fakeUserModel = {
    find: fakeFind,
}

const userService = new UserService(fakeUserModel);
const userRecords = await userService.getAll();

// should return the correct result
expect(userRecords).toEqual(whatever);

// should execute find
expect(fakeFind).toHaveBeenCalledTimes(1);

// should execute select with 'name' parameter
expect(fakeSelect).toHaveBeenCalledTimes(1);
expect(fakeSelect).toHaveBeenCalledWith('name');

// should execute catch with this.errorHandler
expect(fakeCatch).toHaveBeenCalledWith(userService.errorHandler);
class-SomeClass{
公共异步getAll(){
const userRecords=wait this.userModel.find().select('name').catch(this.errorHandler);
返回用户记录;
}
公共错误处理程序(e){
抛出新的HttpException(500,“获取用户时出错”,e);
}
}
//这只是一个示例,它应该与预期返回的输出类型相同
const whatever=Math.random();
const fakeCatch=jest.fn(()=>随便什么);
const fakeSelect=jest.fn(()=>{
返回{
捕获:伪造捕获
}
});
const fakeFind=jest.fn(()=>{
返回{
选择:fakeSelect
};
});
常量fakeUserModel={
查找:伪造查找,
}
const userService=新的userService(fakeUserModel);
const userRecords=await userService.getAll();
//应该返回正确的结果
expect(用户记录)。toEqual(无论什么);
//应该执行find
期望(伪造发现)。被催缴的时间(1);
//应使用“名称”参数执行select
期望(fakeSelect)。已被催缴时间(1);
期望(fakeSelect)。与('name')一起被调用;
//应该使用this.errorHandler执行catch
expect(fakeCatch).tohavencalledwith(userService.errorHandler);