TypeScript中如何用Jest模拟返回类的Metaplex类编写单元测试?
Jest模拟Metaplex模块的测试方案
针对你的场景,我们可以通过Jest的模块模拟能力,完整覆盖findAllByOwner的参数验证和返回值模拟,以下是具体实现步骤:
1. 模拟Metaplex模块与链式调用
由于代码中使用了Metaplex.make()→nfts()→findAllByOwner()的链式调用,需要逐层模拟这些方法的返回值:
在测试文件顶部模拟整个@metaplex-foundation/js-next模块及关联的PublicKey:
// 模拟PublicKey类,用于验证传入的钱包地址 jest.mock('@solana/web3.js', () => ({ PublicKey: jest.fn().mockImplementation((addr) => ({ toString: () => addr })) })); // 模拟Metaplex模块的链式调用结构 jest.mock('@metaplex-foundation/js-next', () => ({ Metaplex: { make: jest.fn().mockReturnValue({ nfts: jest.fn().mockReturnValue({ findAllByOwner: jest.fn() }) }) }, Nft: {} // 若后续需要用到Nft类型,可在此补充mock定义 }));
2. 编写测试用例
编写测试用例验证参数传递和数据处理逻辑:
import { Metaplex, Nft } from "@metaplex-foundation/js-next"; import { PublicKey } from "@solana/web3.js"; import { doSomething } from "./your-module-path"; // 替换为实际模块路径 describe('doSomething', () => { beforeEach(() => { // 重置所有mock,避免测试用例间状态污染 jest.clearAllMocks(); }); it('应正确传入walletAddress并处理返回数据', async () => { // 1. 预设mock返回值 const mockNfts: Partial<Nft>[] = [ { name: 'Test NFT 1', owner: new PublicKey('test-owner-1') }, { name: 'Test NFT 2', owner: new PublicKey('test-owner-2') } ]; const mockFindAllByOwner = (Metaplex.make as jest.Mock).mockReturnValue.nfts().findAllByOwner; mockFindAllByOwner.mockResolvedValue(mockNfts); // 2. 调用目标方法 const testWalletAddr = 'test-wallet-address'; const result = await doSomething(testWalletAddr); // 3. 验证调用链与参数 expect(Metaplex.make).toHaveBeenCalledWith(QuickNodeService.connection); expect((Metaplex.make as jest.Mock).mockReturnValue.nfts).toHaveBeenCalled(); // 验证findAllByOwner传入了正确的PublicKey实例 expect(mockFindAllByOwner).toHaveBeenCalledWith(expect.any(PublicKey)); // 验证PublicKey构造时使用了目标钱包地址 expect(PublicKey).toHaveBeenCalledWith(testWalletAddr); // 4. 验证数据处理结果(根据MyType的实际定义调整断言) expect(result).toEqual(/* 预期的MyType结构结果 */); }); });
关键说明
- 链式调用模拟:通过
mockReturnValue逐层返回包含下一级方法的对象,确保调用链能正常执行。 - 参数验证:通过
expect.any(PublicKey)验证类型,结合PublicKey的mock构造函数验证原始地址参数。 - 测试隔离:每个测试用例前调用
jest.clearAllMocks(),避免不同用例的mock状态互相干扰。
内容的提问来源于stack exchange,提问作者joannaz
相关产品推荐
相关产品推荐

