您如何模拟和扩展外部定义的 class 及其原型?
How do you mock & extend an external defined class and it's prototypes?
背景故事
我正在玩一个名为 screeps 的游戏,该游戏允许您编写一个在游戏中执行动作的机器人/人工智能。实现这一点的方法是在具有可用常量、classes 和定义的环境中上传 运行 代码。
这些定义是用以下包定义的
https://www.npmjs.com/package/@types/screeps
现在我正在用 typescript 编写代码并使用 rollup 为 screeps 编译它,我正在使用以下入门包
https://github.com/screepers/screeps-typescript-starter
我正在尝试使用以下框架进行模拟
https://www.npmjs.com/package/@fluffy-spoon/substitute
问题
当 运行ning 在 mocha 中时,我必须从游戏中存根/模拟环境的功能,当 运行ning 在测试框架中时它不存在。
在其他人的帮助下,我已经设法模拟常量并在 mocha 中使用它们 运行。但现在我坚持扩展对象的原型 Creep
prototypes.ts
Object.defineProperty(Creep.prototype, "task", {
get() {
... logic
},
set(task: ITask | null) {
... logic
}
})
测试
import "../constants"
import "../../src/tasks/prototypes"
import { Task } from "tasks/Task"
import { Game, Memory } from "./mock"
import { assert } from "chai"
import { Substitute, Arg } from "@fluffy-spoon/substitute"
describe("tasks", () => {
before(() => {
// runs before all test in this block
})
beforeEach(() => {
// runs before each test in this block
// @ts-ignore : allow adding Game to global
global.Game = _.clone(Game) as Game
// @ts-ignore : allow adding Memory to global
global.Memory = _.clone(Memory)
})
it("Creep should have extended prototyped", () => {
const testCreep = Substitute.for<Creep>()
const task = testCreep.task
assert.isNotNull(task)
})
})
当我 运行 测试时出现以下错误
...\dist\test-unit.bundle.js:3324
}(chai));
^
ReferenceError: Creep is not defined
这是有道理的,因为 creep class 还没有被游戏引擎或测试环境定义,所以导入 prototypes.ts 无法扩展它
但我不确定如何真正让它发挥作用。
我按照我在常量定义中所做的事情运行设法得到了它运行
mock.ts
import { Substitute, Arg } from "@fluffy-spoon/substitute"
export const Game = Substitute.for<Game>()
const mockScreeps = () => {
const g = global as any
g.Game = Game
g.Creep = (function() {
function Creep() {}
return Creep
})()
g.RoomObject = (function() {
function RoomObject() {}
return RoomObject
})()
g.RoomPosition = (function() {
function RoomObject() {}
return RoomObject
})()
}
mockScreeps()
测试
import "../constants"
import { Memory } from "./mock"
import { assert } from "chai"
import "../../src/tasks/prototypes"
describe("tasks", () => {
before(() => {
// runs before all test in this block
})
beforeEach(() => {
// runs before each test in this block
// @ts-ignore : allow adding Memory to global
global.Memory = _.clone(Memory)
})
it("Creep should have extended prototyped", () => {
const creep = new Creep("test")
creep.memory = {
task: {
tick: 123,
name: "dummy"
}
}
const task = creep.task
assert.isNotNull(task)
if (task && creep.memory.task) {
assert.isString(task.memory.name)
assert.equal(task.memory.name, creep.memory.task.name)
}
})
})
它现在运行我的测试,我只需要在使用尚未模拟的东西进行测试时扩展模拟。
背景故事
我正在玩一个名为 screeps 的游戏,该游戏允许您编写一个在游戏中执行动作的机器人/人工智能。实现这一点的方法是在具有可用常量、classes 和定义的环境中上传 运行 代码。
这些定义是用以下包定义的 https://www.npmjs.com/package/@types/screeps
现在我正在用 typescript 编写代码并使用 rollup 为 screeps 编译它,我正在使用以下入门包 https://github.com/screepers/screeps-typescript-starter
我正在尝试使用以下框架进行模拟 https://www.npmjs.com/package/@fluffy-spoon/substitute
问题
当 运行ning 在 mocha 中时,我必须从游戏中存根/模拟环境的功能,当 运行ning 在测试框架中时它不存在。
在其他人的帮助下,我已经设法模拟常量并在 mocha 中使用它们 运行。但现在我坚持扩展对象的原型 Creep
prototypes.ts
Object.defineProperty(Creep.prototype, "task", {
get() {
... logic
},
set(task: ITask | null) {
... logic
}
})
测试
import "../constants"
import "../../src/tasks/prototypes"
import { Task } from "tasks/Task"
import { Game, Memory } from "./mock"
import { assert } from "chai"
import { Substitute, Arg } from "@fluffy-spoon/substitute"
describe("tasks", () => {
before(() => {
// runs before all test in this block
})
beforeEach(() => {
// runs before each test in this block
// @ts-ignore : allow adding Game to global
global.Game = _.clone(Game) as Game
// @ts-ignore : allow adding Memory to global
global.Memory = _.clone(Memory)
})
it("Creep should have extended prototyped", () => {
const testCreep = Substitute.for<Creep>()
const task = testCreep.task
assert.isNotNull(task)
})
})
当我 运行 测试时出现以下错误
...\dist\test-unit.bundle.js:3324
}(chai));
^
ReferenceError: Creep is not defined
这是有道理的,因为 creep class 还没有被游戏引擎或测试环境定义,所以导入 prototypes.ts 无法扩展它 但我不确定如何真正让它发挥作用。
我按照我在常量定义中所做的事情运行设法得到了它运行
mock.ts
import { Substitute, Arg } from "@fluffy-spoon/substitute"
export const Game = Substitute.for<Game>()
const mockScreeps = () => {
const g = global as any
g.Game = Game
g.Creep = (function() {
function Creep() {}
return Creep
})()
g.RoomObject = (function() {
function RoomObject() {}
return RoomObject
})()
g.RoomPosition = (function() {
function RoomObject() {}
return RoomObject
})()
}
mockScreeps()
测试
import "../constants"
import { Memory } from "./mock"
import { assert } from "chai"
import "../../src/tasks/prototypes"
describe("tasks", () => {
before(() => {
// runs before all test in this block
})
beforeEach(() => {
// runs before each test in this block
// @ts-ignore : allow adding Memory to global
global.Memory = _.clone(Memory)
})
it("Creep should have extended prototyped", () => {
const creep = new Creep("test")
creep.memory = {
task: {
tick: 123,
name: "dummy"
}
}
const task = creep.task
assert.isNotNull(task)
if (task && creep.memory.task) {
assert.isString(task.memory.name)
assert.equal(task.memory.name, creep.memory.task.name)
}
})
})
它现在运行我的测试,我只需要在使用尚未模拟的东西进行测试时扩展模拟。