【问题标题】:How to Mock postgresql (pg) in node.js using Jasmine or third party lib?如何使用 Jasmine 或第三方库在 node.js 中模拟 postgresql (pg)?
【发布时间】:2021-12-18 03:53:21
【问题描述】:

我有一个查询 postgres 数据库 (node-postgres lib) 并从中检索数据并将其映射到平面数组的方法。

export const getActiveUsersLast7DaysForProject = async (projectId: string): Promise<User[]> => {
  let userIds: string[] = [];
  const client = new PG.Client(config.encryptedCredentials); // prod only
  await client.connect();

  await client
    .query(
      '
      SELECT user_id FROM my_db.users_active ua
      WHERE ua.project_id='12345'
      GROUP BY user_id'
    )
    .then(
      (res: any) => (userIds = res.rows.flatMap((user: any) => user.user_id))
    )
    .catch((e: Error) => console.error(e.stack));

  return userIds;
};

如何测试它?当前,当它尝试在本地连接到数据库时测试失败(正如预期的那样,因为凭据不适用于 localhost)。我可以存根/模拟query() 以返回一些测试查询结果吗?

另外,如何拦截对真实数据库的调用并使用模拟数据库,例如pg-mem

【问题讨论】:

    标签: node.js postgresql jasmine node-postgres


    【解决方案1】:

    您可以使用spyOn() 模拟PG.Client 类并使用jasmine.createSpyObj()PG.Client 类的实例创建spy obj。

    注意:通过模拟查询结果进行测试并不能保证您的 SQL 语句是正确的,只测试应用程序代码。

    这是单元测试,存根副作用 I/O 操作。

    index.ts:

    import PG from 'pg';
    
    const config = {
      encryptedCredentials: {
        host: 'my.database-server.com',
        port: 5334,
        user: 'database-user',
        password: 'secretpassword!!',
      },
    };
    export const getActiveUsersLast7DaysForProject = async (projectId: string): Promise<string[]> => {
      let userIds: string[] = [];
      const client = new PG.Client(config.encryptedCredentials);
      await client.connect();
    
      await client
        .query(
          `
          SELECT user_id FROM my_db.users_active ua
          WHERE ua.project_id='12345'
          GROUP BY user_id`,
        )
        .then((res: any) => (userIds = res.rows.flatMap((user: any) => user.user_id)))
        .catch((e: Error) => console.error(e.stack));
    
      return userIds;
    };
    

    index.test.ts:

    import { getActiveUsersLast7DaysForProject } from './';
    import PG, { Client } from 'pg';
    
    describe('69830430', () => {
      it('should pass', async () => {
        const mClient: jasmine.SpyObj<Client> = jasmine.createSpyObj('client', ['connect', 'query']);
        mClient.query.and.resolveTo({ rows: [{ user_id: '1' }, { user_id: '2' }] });
        spyOn(PG, 'Client').and.returnValue(mClient);
        const actual = await getActiveUsersLast7DaysForProject('1');
        expect(actual).toEqual(['1', '2']);
        expect(mClient.connect).toHaveBeenCalled();
        expect(mClient.query).toHaveBeenCalled();
      });
    });
    

    测试结果:

    Executing 1 defined specs...
    Running in random order... (seed: 89766)
    
    Test Suites & Specs:
    
    1. 69830430
       ✔ should pass (6ms)
    
    >> Done!
    
    
    Summary:
    
    ?  Passed
    Suites:  1 of 1
    Specs:   1 of 1
    Expects: 3 (0 failures)
    Finished in 0.013 seconds
    

    【讨论】:

      猜你喜欢
      • 2019-12-14
      • 1970-01-01
      • 2010-09-26
      • 2018-02-19
      • 2018-11-17
      • 1970-01-01
      • 1970-01-01
      • 2018-05-07
      相关资源
      最近更新 更多