Jest expect.objectContaining 失败,即使期望的对象是接收到的一部分。

huangapple go评论78阅读模式
英文:

Jest expect.objectContaining fails even if expected object is part of received

问题

// in my .test.ts file

describe('test', () => {
  const mockHandler = jest.fn(async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
    return {
      statusCode: 200,
      body: ''
    };
  });

  it('event should contain assigned value', () => {
    const request = {
      event: {
        requestContext: {
          authorizer: {
            claims: {
              'custom:SomeClaimA': 'claimA',
              'custom:SomeClaimB': '1'
            }
          }
        }
      }
    };

    const middleware = middy(mockHandler).use(myCustomMiddleware('somedata'));
    await middleware.before(request as never);

    expect(mockHandler).toHaveBeenCalledWith(expect.objectContaining({ importantData:'important' }));
  });
});
英文:

I want to test my middy middleware for my lambda handler using jest. In the middleware I assign a propperty to the request.event which then will be used in the handler.

//hander.ts 

const main = async (event: APIGatewayProxyEvent): Promise&lt;APIGatewayProxyResult&gt; =&gt; {
  return {
    statusCode: 200,
    body: `some`
  };
};

export const handler = middy(main)
  .use(myCustomMiddware(&#39;somedata&#39;));

// myCustomMiddleware.ts
export const myCustomMiddleware = (data: string): middy.MiddlewareObj&lt;APIGatewayProxyEvent, APIGatewayProxyResult&gt; =&gt; {
  const before: middy.MiddlewareFn&lt;APIGatewayProxyEvent, APIGatewayProxyResult&gt; = async (request): Promise&lt;void&gt; =&gt; {
    // Do stuff
    Object.assign(request.event, { importantData: &#39;important&#39; } as { importantData: string });
  };
};
return {
  before
};

Now I want to write a test if the handler receives the correct value:

// in my .test.ts file


describe(&#39;test&#39;, () =&gt; {
  const mockHandler = jest.fn(async (event: APIGatewayProxyEvent): Promise&lt;APIGatewayProxyResult&gt; =&gt; {
    return {
      statusCode: 200,
      body: &#39;&#39;
    };
  });

  it(&#39;event should contain assigned value&#39;, () =&gt; {
    const request = {
      event: {
        requestContext: {
          authorizer: {
            claims: {
              &#39;custom:SomeClaimA&#39;: &#39;claimA&#39;,
              &#39;custom:SomeClaimB&#39;: &#39;1&#39;
            }
          }
        }
      }
    };


    const middleware = middy(mockHandler).use(myCustomMiddleware(&#39;somedata&#39;));
    await middleware.before(request as never);

    expect(mockHandler).toHaveBeenCalledWith(expect.objectContaining({ importantData:&#39;important&#39;} ));
  });

But for some reason jest tells me that the importantData is not part of the received parameter when it actually is. This is the output I get from the jest runner:

Error: expect(jest.fn()).toHaveBeenCalledWith(...expected)

Expected: ObjectContaining {&quot;importantData&quot;: &quot;important&quot;}
Received: {&quot;importantData&quot;: &quot;important&quot;, &quot;requestContext&quot;: {&quot;authorizer&quot;: {&quot;claims&quot;: {&quot;custom:SomeClaimA&quot;: &quot;SomeClaimA&quot;, &quot;custom:SomeClaimB&quot;: &quot;1&quot;}}}}, {}

答案1

得分: 1

所以这是因为显然 middy 在底层调用基本处理程序,它接收两个参数 await baseHandler(request.event, request.context);

一个提示应该是测试运行程序的输出末尾的 {}

所以更新后的匹配器应该像这样:

expect(mockHandler)
    .toHaveBeenCalledWith(expect.objectContaining({ 
        importantData: 'important' }), expect.anything());

这会引发一个断言,所以你必须在测试开始时添加 expect.assertions(1)

我不完全明白为什么会发生断言,但我认为 .toHaveBeenCalledWith 会引发一个,因为我们没有一个精确的匹配。

英文:

So the reason for this is that apparently middy calls the base handler under the hood which receives two arguments await baseHandler(request.event, request.context);

A hint should've been the {} at the end of the Received output of the testrunner.

So the updated matcher should look like this:

    expect(mockHandler)
    .toHaveBeenCalledWith(expect.objectContaining({ 
     importantData:&#39;important&#39;} ), expect.anything());

This raises an assertion so you have to add expect.assertions(1) at the start of the test.

I not completely understand why an assertion is happening, but I assume that .toHaveBeenCalledWith raises one since we do not have an exact match?

huangapple
  • 本文由 发表于 2023年2月24日 00:32:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75547680.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定