【问题标题】:Disable a single nock scope immediately to re-setup a mocked URL立即禁用单个 nock 范围以重新设置模拟 URL
【发布时间】:2023-04-09 18:08:01
【问题描述】:

使用nock,有没有办法禁用单个诺克范围? 我一直在努力进行一些设置与其他测试相同 URL 的 nocks 的测试。它们都单独运行良好,但是当在同一个 mocha 会话中运行时,其中一个会失败,因为我无法重新锁定活动的 nock 范围,这意味着设置的 nocks 会捕获所有请求。

我尝试过的:

  • 如果我在before() 中设置了一些nocks,然后在我的after() 中调用scope.persist(false),它只会“取消保留”范围,以便它对一个请求有效。它不会立即禁用它。
  • 我发现nock.cleanAll() 会立即禁用 nocks,以便可以再次设置它们,但随后它禁用可能已经设置过一次的所有全局 nocks,对所有测试用例。

到目前为止,我发现的唯一解决方案是 1) 对所有 nocks 使用唯一的 URL:s,这并不总是可行的,或者 2) 使用 nock.cleanAll() 并且不依赖任何全局 nocks -而是确保只在本地 before() 函数中设置 nocks,包括为每个需要它们的测试重复设置全局函数。

能做到这一点似乎非常有用

scope = nock('http://somewhere.com').persist().get('/'.reply(200, 'foo');

然后在一堆测试中使用那个诺克,最后做

scope.remove();

但是,我无法做到这样的事情。有可能吗?

例子:

before(async () => {
   nock('http://common').persist().get('/').reply(200, 'common');
});

after(async () => {
});

describe('Foo tests', () => {
    let scope;
    before(async () => {
        scope = nock('http://mocked').persist().get('/').reply(200, 'foo');
    });
    after(() => {
        // scope.persist(false); // This causes the Bar tests to use the Foo nocks one more time :(
        // nock.cleanAll(); // This also disables the common nocks
    });
    it('Should get FOO', async () => {
        expect(await fetch('http://mocked').then(res => res.text())).to.equal('foo');
        expect(await fetch('http://common').then(res => res.text())).to.equal('common');
    });
    it('Should get FOO again', async () => {
        expect(await fetch('http://mocked').then(res => res.text())).to.equal('foo');
        expect(await fetch('http://common').then(res => res.text())).to.equal('common');
    });
});

describe('Bar tests', () => {
    let scope;
    before(async () => {
        scope = nock('http://mocked').persist().get('/').reply(200, 'bar');
    });
    after(() => {
        // scope.persist(false);
        // nock.cleanAll();
    });
    it('Should get BAR', async () => {
        expect(await fetch('http://mocked').then(res => res.text())).to.equal('bar');
        expect(await fetch('http://common').then(res => res.text())).to.equal('common');
    });
    it('Should get BAR again', async () => {
        expect(await fetch('http://mocked').then(res => res.text())).to.equal('bar');
        expect(await fetch('http://common').then(res => res.text())).to.equal('common');
    });
});

如果使用 scope.persist(false),这些测试要么在第 3 次测试中失败(因为该测试仍然获得 foo 版本),或者如果使用 nock.cleanAll(),则在第 3 次和第 4 次测试中失败,因为随后移除了常见的 nocks。

【问题讨论】:

    标签: node.js mocha.js nock


    【解决方案1】:

    我也遇到了这个问题,并通过侦听范围发出的request 事件并在触发事件时移除拦截器来找到解决此问题的方法。理想情况下,我认为您应该收听replied 事件,但由于某种原因,当我尝试它时,该事件没有触发,不知道为什么。但是下面的代码对我有用:

    /**
     * @jest-environment node
     */
    
    const nock = require('nock');
    
    describe('Test suite', () => {
    
      test('Test case', async () => {
    
        let interceptor1 = nock('https://example-url.com', {
            reqHeaders: {
              'Content-Type': 'text/xml',
              soapaction: 'http://www.sample.com/servie/getOrders',
            },
          })
          .post('/');
    
        let interceptor2 = nock('https://example-url.com', {
            reqHeaders: {
              soapaction: 'http://www.sample.com/servie/getProducts',
            },
          })
          .post('/');
    
        let scope = interceptor1.replyWithFile(200, path.join(__dirname, './path1.xml'));
        interceptor2.replyWithFile(200, path.join(__dirname, './path.xml'));
    
        scope.on('request', (req, interceptor) => {
          nock.removeInterceptor(interceptor1);
        });
    
        const resp = await asynccall();
        expect(resp).toStrictEqual(exp);
      });
    
    });
    

    【讨论】:

      【解决方案2】:

      如此处所述:Unable to remove interceptors using nock 我找到了一种不存储拦截器的方法,只需再次设置模拟(显然再次返回拦截器),然后在 removeInterceptor() 函数中使用返回的拦截器。这确实返回了true,并且在我的测试中确实有效。

      【讨论】:

        【解决方案3】:

        我为此找到了一个非常简单的解决方法——作用域有一个名为“拦截器”的属性,它是作用域使用的各种拦截器的数组。你可以用你想要的任何东西替换拦截器的“body”属性。

        let scope = nock(base).get(path).reply(200, []).persist();
        testable.call(path).then(console.log);      //returns []
        scope.interceptors[0].body = [1,2,3];
        testable.call(path).then(console.log);      //returns [1,2,3]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-03-27
          • 2017-07-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-10-27
          • 2012-01-30
          相关资源
          最近更新 更多