【问题标题】:Jest fn undefined when used as an object propertyJest fn undefined 当用作对象属性时
【发布时间】:2021-08-22 11:56:44
【问题描述】:

我有一个类,我试图在其中模拟一个对象及其属性

intercept(context: ExecutionContext) {
  const response = contect.switchToHttp().getResponse() // need to mock this chain

  if (response.headersSent) { // to test this path
    return true
  }

  return false
}

如果我使用普通对象字面量和一些匿名函数“模拟”依赖项,一切都会按预期工作

const executionContext = {
  switchToHttp: () => executionContext, // calls itself to simulate 'this' chaining
  getRequest: () => {
    return {
      url: undefined,
      method: undefined,
      headers: undefined,
      connection: {
        remoteAddress: undefined,
        remotePort: undefined
      }
    }
  },
  getResponse: () => {
    return {
      headersSent: true, // but i want an easy way to change this in tests without using a factory
      append: () => undefined
    }
  }
} as unknown as ExecutionContext

it('test', () => {
  const response = myclass.intercept(executionContext);

  expect(response).toBeTrue()
});

当我尝试使用 jest.fn() 模拟一些属性时,我得到了奇怪的结果。

const getResponseSpy = jest.fn(() => {
  return {
    headersSent: false,
    append: () => undefined
  }
});

const executionContext = {
  switchToHttp: () => executionContext,
  getRequest: () => {
    return {
      url: undefined,
      method: undefined,
      headers: undefined,
      connection: {
        remoteAddress: undefined,
        remotePort: undefined
      }
    }
  },
  getResponse: getResponseSpy // easier way to change this
} as unknown as ExecutionContext

此时在我的代码中,我得到了undefined的响应

TypeError: Cannot read property 'headersSent' of undefined

如果我执行getResponse: () => getResponseSpy 之类的操作,那么我的代码中的response 是一个Jest 模拟对象,而不是模拟实现。这当然缺少headersSent 属性。

我觉得我做错了什么。我试过使用

switchToHttp: jest.fn().mockResturnThis()

但它不会改变任何东西。对象内部的玩笑间谍似乎没有返回其模拟实现

我做错了什么?

【问题讨论】:

    标签: javascript typescript unit-testing testing jestjs


    【解决方案1】:

    mockFn.mockReturnThis() 应该可以工作。

    例如

    index.ts:

    interface ExecutionContext {
      switchToHttp(): ExecutionContext;
      getResponse(): ExecutionContext;
      headersSent: boolean;
    }
    
    export const myclass = {
      intercept(context: ExecutionContext) {
        const response = context.switchToHttp().getResponse();
    
        if (response.headersSent) {
          return true;
        }
    
        return false;
      },
    };
    

    index.test.ts:

    import { myclass } from './';
    
    describe('67837058', () => {
      it('should pass', () => {
        const executionContext = {
          switchToHttp: jest.fn().mockReturnThis(),
          getResponse: jest.fn().mockReturnThis(),
          headersSent: true,
        };
        const response = myclass.intercept(executionContext);
        expect(response).toBeTruthy();
      });
    });
    

    测试结果:

     PASS  examples/67837058/index.test.ts (8.387 s)
      67837058
        ✓ should pass (3 ms)
    
    ----------|---------|----------|---------|---------|-------------------
    File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    ----------|---------|----------|---------|---------|-------------------
    All files |      80 |       50 |     100 |      80 |                   
     index.ts |      80 |       50 |     100 |      80 | 15                
    ----------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        9.273 s
    

    【讨论】:

    • 我澄清了这个问题,我不认为它与链接有关
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多