如何更改模拟类方法的返回值

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

How to change return value of mocked class method

问题

我有一个模拟的类,它是一个节点模块,其中包含以下方法,并且我需要更改methodOne的返回值。

jest.mock("module_name", () => {
  return {
    __esModule: true,
    Abc: class Abc {
      constructor(config) {}

      async methodOne(params) {
        return {
          message: {
            content:
              '我需要更改的文本',
          },
        };
      }
    },
    Configuration: class Configuration {
      constructor(config) {
        return true;
      }
    },
  };
});

describe("getVeganStatus", () => {
  it("应该处理第一种情况......", async () => {
    // methodOne 的 message.content 返回值应为 "ABC"
  })

  it("应该处理第二种情况......", async () => {
    // methodOne 的 message.content 返回值应为 "XYZ"
  });
})
英文:

I have a mocked class of a node module and its method as below, and test case to test case I need to change the methodOne returning value.

jest.mock("module_name", () => {
  return {
    __esModule: true,
    Abc: class Abc {
      constructor(config) {}

      async methodOne(params) {
        return {
          message: {
            content:
              'This text I need to change',
          },
        };
      }
    },
    Configuration: class Configuration {
      constructor(config) {
        return true;
      }
    },
  };
});

describe("getVeganStatus", () => {
  it("should handle case one......", async () => {
    // methodOne message.content return value should be "ABC"
  })

  it("should handle case two......", async () => {
    // methodOne message.content return value should be "XYZ"
  });
})```

</details>


# 答案1
**得分**: 1

根据[使用`mockImplementation()`或`mockImplementationOnce()`替换模拟](https://jestjs.io/docs/es6-class-mocks#replacing-the-mock-using-mockimplementation-or-mockimplementationonce)文档的说明:

`jest.mock`的调用会被提升到代码的顶部。你可以在稍后的代码中指定一个模拟,例如在`beforeAll()`中,通过在现有的模拟上调用`mockImplementation()`(或`mockImplementationOnce()`)来替换工厂参数。**如果需要的话,这也允许你在测试之间更改模拟**:

例如:

`some-module.js`:
```js
export class Abc {
  constructor(config) {}

  async methodOne(params) {
    return {
      message: {
        content:
          'This text I need to change',
      },
    };
  }
}

main.js:

import { Abc } from './some-module';

export async function main() {
	const abc = new Abc();
	return abc.methodOne().then((res) => res.message.content);
}

main.test.js:

import { main } from './main';
import { Abc } from './some-module';

jest.mock('./some-module');

describe('76863882', () => {
	test('should pass 1', async () => {
		Abc.mockImplementation(() => {
			return {
				methodOne: async () => ({ message: { content: 'ABC' } }),
			};
		});
		const actual = await main();
		expect(actual).toBe('ABC');
	});

	test('should pass 2', async () => {
		Abc.mockImplementation(() => {
			return {
				methodOne: async () => ({ message: { content: 'XYZ' } }),
			};
		});
		const actual = await main();
		expect(actual).toBe('XYZ');
	});
});

测试结果:

 PASS  stackoverflow/76863882/main.test.js (5.787 s)
  76863882
    ✓ should pass 1 (2 ms)
    ✓ should pass 2

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        5.978 s, estimated 6 s
Ran all test suites related to changed files.
英文:

Following Replacing the mock using mockImplementation() or mockImplementationOnce() documentation.

> Calls to jest.mock are hoisted to the top of the code. You can specify a mock later, e.g. in beforeAll(), by calling mockImplementation() (or mockImplementationOnce()) on the existing mock instead of using the factory parameter. This also allows you to change the mock between tests, if needed:

E.g.

some-module.js:

export class Abc {
  constructor(config) {}

  async methodOne(params) {
    return {
      message: {
        content:
          &#39;This text I need to change&#39;,
      },
    };
  }
}

main.js:

import { Abc } from &#39;./some-module&#39;;

export async function main() {
	const abc = new Abc();
	return abc.methodOne().then((res) =&gt; res.message.content);
}

main.test.js:

import { main } from &#39;./main&#39;;
import { Abc } from &#39;./some-module&#39;;

jest.mock(&#39;./some-module&#39;);

describe(&#39;76863882&#39;, () =&gt; {
	test(&#39;should pass 1&#39;, async () =&gt; {
		Abc.mockImplementation(() =&gt; {
			return {
				methodOne: async () =&gt; ({ message: { content: &#39;ABC&#39; } }),
			};
		});
		const actual = await main();
		expect(actual).toBe(&#39;ABC&#39;);
	});

	test(&#39;should pass 2&#39;, async () =&gt; {
		Abc.mockImplementation(() =&gt; {
			return {
				methodOne: async () =&gt; ({ message: { content: &#39;XYZ&#39; } }),
			};
		});
		const actual = await main();
		expect(actual).toBe(&#39;XYZ&#39;);
	});
});

Test result:

 PASS  stackoverflow/76863882/main.test.js (5.787 s)
  76863882
    ✓ should pass 1 (2 ms)
    ✓ should pass 2

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        5.978 s, estimated 6 s
Ran all test suites related to changed files.

huangapple
  • 本文由 发表于 2023年8月9日 08:35:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76863882.html
匿名

发表评论

匿名网友

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

确定