You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Mocha中Mock并扩展Screeps的Creep类及其原型?

解决Screeps TypeScript测试中Creep原型扩展的ReferenceError问题

这个错误的核心原因很明确:你的测试环境里完全没有Screeps原生的Creep类定义,当你导入prototypes.ts时,代码尝试访问Creep.prototype,但找不到这个类,自然就抛出了ReferenceError。下面是我亲测有效的解决步骤:

1. 先在测试环境中定义基础的Creep类

因为@types/screeps提供的Creep是一个接口,我们需要创建一个空的类来实现这个接口,并且把它挂载到全局对象上,这样原型扩展代码就能找到目标了。

你可以在测试文件最前面添加这段代码,或者把它抽成单独的mock文件复用:

import type { Creep as ScreepsCreep } from '@types/screeps';

// 创建一个基础的Creep类,实现Screeps的Creep接口
class Creep implements ScreepsCreep {
  // 只需要添加必要的基础属性,或者用索引签名绕过未实现的属性检查
  id = 'test-creep-id';
  name = 'test-creep';
  [key: string]: any; // 允许任意属性,避免类型报错
}

// 将这个类挂载到全局,让prototypes.ts能访问到
global.Creep = Creep;

2. 调整导入顺序,确保Creep定义在前

原来的导入顺序是先加载原型扩展,这时候Creep还没定义,所以一定要先完成Creep的全局挂载,再导入prototypes.ts:

// 先导入测试依赖和mock基础
import { Game, Memory } from "./mock";
import { assert } from "chai";
import { Substitute, Arg } from "@fluffy-spoon/substitute";
import type { Creep as ScreepsCreep } from '@types/screeps';

// 第一步:定义并挂载Creep到全局
class Creep implements ScreepsCreep {
  id = 'test-creep-id';
  name = 'test-creep';
  [key: string]: any;
}
global.Creep = Creep;

// 第二步:现在再导入原型扩展和业务代码
import "../constants";
import "../../src/tasks/prototypes";
import { Task } from "tasks/Task";

3. 正确创建Mock Creep实例

现在测试环境已经有了Creep的定义,你可以用@fluffy-spoon/substitute正常创建Mock实例了。注意如果需要模拟task属性的get/set逻辑,可以给Mock设置返回值或行为:

describe("tasks", () => {
  beforeEach(() => {
    // 重置全局Game和Memory
    // @ts-ignore
    global.Game = _.clone(Game) as Game;
    // @ts-ignore
    global.Memory = _.clone(Memory);
  });

  it("Creep should have extended prototype", () => {
    const testCreep = Substitute.for<ScreepsCreep>();
    
    // 根据你的task getter逻辑,设置Mock的返回值
    testCreep.task.returns(null); // 或者你预期的初始值
    
    const task = testCreep.task;
    assert.isNotNull(task); // 这里根据你的实际逻辑调整断言
  });
});

可选:抽离Mock代码到单独文件

如果多个测试文件都需要用到Creep的Mock,把上面的Creep类定义放到src/test/mock-creep.ts里,然后在测试文件里导入并挂载:

// mock-creep.ts
import type { Creep as ScreepsCreep } from '@types/screeps';

export class Creep implements ScreepsCreep {
  id = 'test-creep-id';
  name = 'test-creep';
  [key: string]: any;
}

在测试文件中使用:

import { Creep } from './mock-creep';
global.Creep = Creep;

这样做的好处是避免重复代码,保持测试文件整洁。

内容的提问来源于stack exchange,提问作者thmsn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:07:03