Javascript Jest:只能在运行单个测试时重新模拟实现

Javascript Jest:只能在运行单个测试时重新模拟实现,javascript,jestjs,Javascript,Jestjs,我有下面的简化示例,其中我手动模拟依赖项并让它返回已解决的承诺。在我的一个测试中,我尝试将其返回类型更改为承诺拒绝 如果我同时运行所有3个测试,它们都会失败,因为拒绝测试中的调用实际上已解决。但是,如果我将规范中的第17行修改为it.only('如果客户端未能加载,则应拒绝'),则单个测试通过 我做错了什么 service.js: import client from './client'; const service = (() => { let instance; cons

我有下面的简化示例,其中我手动模拟依赖项并让它返回已解决的承诺。在我的一个测试中,我尝试将其返回类型更改为承诺拒绝

如果我同时运行所有3个测试,它们都会失败,因为拒绝测试中的调用实际上已解决。但是,如果我将规范中的第17行修改为
it.only('如果客户端未能加载,则应拒绝'
),则单个测试通过

我做错了什么

service.js

import client from './client';

const service = (() => {
  let instance;

  const makeCall = () => {
    return true;
  };

  const init = async () => {
    const _client = await client();

    return Promise.resolve({
      makeCall,
    });
  };

  const getInstance = async () => {
    if (!instance) {
      instance = await init();
    }

    return Promise.resolve(instance);
  };

  return {
    getInstance,
  };
})();

export default service;
const client = () => Promise.resolve('Real');

export default client;
import client from '../client';
import service from '../service';

jest.mock('../client');

describe('Service', () => {
  it('should return a singleton', () => {
    expect(service.getInstance()).toEqual(service.getInstance());
  });

  it('should resolve if the client successfully loads', async () => {
    expect.assertions(1);

    await expect(service.getInstance()).resolves.toHaveProperty('makeCall');
  });

  it('should reject if the client fails to load', async () => {
    const errorMessage = 'Client could not be initialised.';

    expect.assertions(1);
    client.mockReturnValueOnce(Promise.reject(new Error(errorMessage)));

    await expect(service.getInstance()).rejects.toHaveProperty(
      'message',
      errorMessage
    );
  });
});
const client = jest.fn();
client.mockImplementation(() => {
  return Promise.resolve('Mock file');
});

export default client;
client.js

import client from './client';

const service = (() => {
  let instance;

  const makeCall = () => {
    return true;
  };

  const init = async () => {
    const _client = await client();

    return Promise.resolve({
      makeCall,
    });
  };

  const getInstance = async () => {
    if (!instance) {
      instance = await init();
    }

    return Promise.resolve(instance);
  };

  return {
    getInstance,
  };
})();

export default service;
const client = () => Promise.resolve('Real');

export default client;
import client from '../client';
import service from '../service';

jest.mock('../client');

describe('Service', () => {
  it('should return a singleton', () => {
    expect(service.getInstance()).toEqual(service.getInstance());
  });

  it('should resolve if the client successfully loads', async () => {
    expect.assertions(1);

    await expect(service.getInstance()).resolves.toHaveProperty('makeCall');
  });

  it('should reject if the client fails to load', async () => {
    const errorMessage = 'Client could not be initialised.';

    expect.assertions(1);
    client.mockReturnValueOnce(Promise.reject(new Error(errorMessage)));

    await expect(service.getInstance()).rejects.toHaveProperty(
      'message',
      errorMessage
    );
  });
});
const client = jest.fn();
client.mockImplementation(() => {
  return Promise.resolve('Mock file');
});

export default client;
\uuuu测试/service.spec.js

import client from './client';

const service = (() => {
  let instance;

  const makeCall = () => {
    return true;
  };

  const init = async () => {
    const _client = await client();

    return Promise.resolve({
      makeCall,
    });
  };

  const getInstance = async () => {
    if (!instance) {
      instance = await init();
    }

    return Promise.resolve(instance);
  };

  return {
    getInstance,
  };
})();

export default service;
const client = () => Promise.resolve('Real');

export default client;
import client from '../client';
import service from '../service';

jest.mock('../client');

describe('Service', () => {
  it('should return a singleton', () => {
    expect(service.getInstance()).toEqual(service.getInstance());
  });

  it('should resolve if the client successfully loads', async () => {
    expect.assertions(1);

    await expect(service.getInstance()).resolves.toHaveProperty('makeCall');
  });

  it('should reject if the client fails to load', async () => {
    const errorMessage = 'Client could not be initialised.';

    expect.assertions(1);
    client.mockReturnValueOnce(Promise.reject(new Error(errorMessage)));

    await expect(service.getInstance()).rejects.toHaveProperty(
      'message',
      errorMessage
    );
  });
});
const client = jest.fn();
client.mockImplementation(() => {
  return Promise.resolve('Mock file');
});

export default client;
\uuuu mocks\uuuu/client.js

import client from './client';

const service = (() => {
  let instance;

  const makeCall = () => {
    return true;
  };

  const init = async () => {
    const _client = await client();

    return Promise.resolve({
      makeCall,
    });
  };

  const getInstance = async () => {
    if (!instance) {
      instance = await init();
    }

    return Promise.resolve(instance);
  };

  return {
    getInstance,
  };
})();

export default service;
const client = () => Promise.resolve('Real');

export default client;
import client from '../client';
import service from '../service';

jest.mock('../client');

describe('Service', () => {
  it('should return a singleton', () => {
    expect(service.getInstance()).toEqual(service.getInstance());
  });

  it('should resolve if the client successfully loads', async () => {
    expect.assertions(1);

    await expect(service.getInstance()).resolves.toHaveProperty('makeCall');
  });

  it('should reject if the client fails to load', async () => {
    const errorMessage = 'Client could not be initialised.';

    expect.assertions(1);
    client.mockReturnValueOnce(Promise.reject(new Error(errorMessage)));

    await expect(service.getInstance()).rejects.toHaveProperty(
      'message',
      errorMessage
    );
  });
});
const client = jest.fn();
client.mockImplementation(() => {
  return Promise.resolve('Mock file');
});

export default client;

这是由于试图模拟单例的依赖关系造成的

在运行所有三个测试时,将使用原始的模拟实现(解析),然后不会被拒绝的第二个模拟实现替换

还值得注意的是,由于被拒绝的承诺是创建的,但因此没有得到处理,这会导致未经处理的承诺被拒绝,测试套件崩溃