我如何在要尝试开玩笑的类中模拟私有属性

克里斯·施密茨

我有一个要测试的类方法:

setStepResolution(resolution: stepResolution): void {
        switch (resolution) {
            case stepResolution.FULL_SETUP:
                this.stepperMotors.left.ms1Pin.digitalWrite(0)
                this.stepperMotors.left.ms2Pin.digitalWrite(0)
                this.stepperMotors.left.ms3Pin.digitalWrite(1)
                this.stepperMotors.right.ms1Pin.digitalWrite(0)
                this.stepperMotors.right.ms2Pin.digitalWrite(0)
                this.stepperMotors.right.ms3Pin.digitalWrite(1)
                break
            case stepResolution.HALF_STEP:
                this.stepperMotors.left.ms1Pin.digitalWrite(1)
                this.stepperMotors.left.ms2Pin.digitalWrite(0)
                this.stepperMotors.left.ms3Pin.digitalWrite(0)
                this.stepperMotors.right.ms1Pin.digitalWrite(1)
                this.stepperMotors.right.ms2Pin.digitalWrite(0)
                this.stepperMotors.right.ms3Pin.digitalWrite(0)
                break

这些digitalWrite调用中的每一个都针对在构造我的类时创建的不同类的实例:

export default class BotController {

    private stepperMotors: StepperMotorCollection

    constructor() {
        this.initalizeMotors()
    }

    private initalizeMotors(): void {
        this.stepperMotors = {
            left: {
                directionPin: new Gpio(Number(process.env.LEFT_DIRECTION_PIN), { mode: Gpio.OUTPUT }),
                stepPin: new Gpio(Number(process.env.LEFT_STEP_PIN), { mode: Gpio.OUTPUT }),
                ms1Pin: new Gpio(Number(process.env.LEFT_RESOLUTION_PIN_MS1), { mode: Gpio.OUTPUT }),
                ms2Pin: new Gpio(Number(process.env.LEFT_RESOLUTION_PIN_MS2), { mode: Gpio.OUTPUT }),
                ms3Pin: new Gpio(Number(process.env.LEFT_RESOLUTION_PIN_MS3), { mode: Gpio.OUTPUT }),
                stepsPerMM: Number(process.env.LEFT_STEPS_PER_MM),
                swapCoils: Boolean(process.env.LEFT_SWAP_COILS),
            },
            right: {
                directionPin: new Gpio(Number(process.env.RIGHT_DIRECTION_PIN), { mode: Gpio.OUTPUT }),
                stepPin: new Gpio(Number(process.env.RIGHT_STEP_PIN), { mode: Gpio.OUTPUT }),
                ms1Pin: new Gpio(Number(process.env.RIGHT_RESOLUTION_PIN_MS1), { mode: Gpio.OUTPUT }),
                ms2Pin: new Gpio(Number(process.env.RIGHT_RESOLUTION_PIN_MS2), { mode: Gpio.OUTPUT }),
                ms3Pin: new Gpio(Number(process.env.RIGHT_RESOLUTION_PIN_MS3), { mode: Gpio.OUTPUT }),
                stepsPerMM: Number(process.env.RIGHT_STEPS_PER_MM),
                swapCoils: Boolean(process.env.RIGHT_SWAP_COILS),
            },
        }
    }

我可以使用类的模拟stepperMotors在测试中属性创建模拟Gpio(我已经模拟其他一些测试的构造函数):

test("can change step resolution", () => {
        // * The step resolution of the stepper motors can be changed via the code.
        // * The settings can be controlled by an enum that denotes each of the possible
        // * resolutions.

        const mockStepperMotorConfiguration: StepperMotorCollection = {
            left: {
                directionPin: new pigpio.Gpio(1),
                stepPin: new pigpio.Gpio(1),
                ms1Pin: new pigpio.Gpio(1),
                ms2Pin: new pigpio.Gpio(1),
                ms3Pin: new pigpio.Gpio(1),
                stepsPerMM: 1,
                swapCoils: false,
            },
            right: {
                directionPin: new pigpio.Gpio(1),
                stepPin: new pigpio.Gpio(1),
                ms1Pin: new pigpio.Gpio(1),
                ms2Pin: new pigpio.Gpio(1),
                ms3Pin: new pigpio.Gpio(1),
                stepsPerMM: 1,
                swapCoils: false,
            },
        }

        // ^ To change the resolution to a full step
        // * send in the full step enum
        newController.setStepResolution(stepResolution.FULL_SETUP)

但是我不能,因为stepperMotor财产是私有的。

有几种方法可以解决此问题(将属性设置为公共,设置属性的设置为公共方法),但似乎都不可行,因为该属性永远不能在类外部访问,因此我只公开了属性或方法支持测试。

还有另一种进行这种测试的方法吗?我知道开玩笑我可以通过替换原型函数来模拟javascript类中的方法,例如:

BotController.prototype.someMethod = jest.fn()
const controller = new BotController

如果这是我要模拟的类,则可以将属性作为模拟实现传递,例如:

jest.mock("../BotController", () => ({
    stepperMotors: mockStepperMotorConfiguration
}))

但是随后,该类中的其他所有内容也将被嘲笑,您将失去这一点。

对我应该如何处理这个有任何想法吗?

更新:尝试创建后门

我正在尝试Taplar创建后门的方法。

我尝试将控制器实例转换为any

后门

But the complier is still yelling at me:

比勒

Another update

After Taplar pointed out how to call the method on the cast version the errors went away on the back door which is fantastic!

The next wall I smashed into was that now for some reason the test can't see my mock anymore which is weird because the variable is local to the test.

更接近

Estus Flask

Unless # hard privacy is used, private properties can be accessed outside a class at runtime, TypeScript access modifiers are applied only at compilation time.

Accessing private members in tests can be considered a reflection.

Visibility can be bypassed with bracket notation, which is the preferable option:

controllerInstance['stepperMotors'] = ...;

Or with Reflect API:

Reflect.set(controllerInstance, 'stepperMotors', ...);

Or by disabling type checks:

(controllerInstance as any).stepperMotors = ...;

由于私有属性是通过原型方法设置的,因此另一种方法是对其进行模拟。如果原始初始化导致不良副作用并需要避免,则适用。BotController.prototype.someMethod = jest.fn()切勿在Jest中使用它,因为它无法自动清理并交叉污染测试。相反,它可能是:

jest.spyOn(BotController.prototype, 'initalizeMotors').mockImplementation(function (this: BotController) {
  this['stepperMotors'] = ...;
});
...
expect(controllerInstance['initalizeMotors']).toHaveBeenCalled();

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Ruby中访问私有类方法?

来自分类Dev

如何在单独的类中访问私有构造函数?

来自分类Dev

如何在子类对象的抽象类中访问私有属性的值?

来自分类Dev

如何在Scala中测试私有类方法?

来自分类Dev

如何在目标C中从超类重写私有方法和属性

来自分类Dev

C ++:如何在类中获取带有动态变量的私有属性?

来自分类Dev

如何在C中模拟C ++中的私有成员变量?

来自分类Dev

开玩笑-如何找到具有ID的渲染DOM组件?

来自分类Dev

如何在RSpec中模拟我的超类

来自分类Dev

如何在es6类中声明私有变量和私有方法

来自分类Dev

如何在Python的类中模拟属性

来自分类Dev

开玩笑预期在模拟vue-multiselect中的vuex操作上已调用了模拟功能

来自分类Dev

如何模拟axios API调用?开玩笑

来自分类Dev

如何在具有私有方法的Jest中模拟HTTP方法

来自分类Dev

开玩笑抱怨错误...我告诉开玩笑期望

来自分类Dev

开玩笑-模拟update()函数

来自分类Dev

开玩笑的手动ES6类模拟未激活,我想了解为什么

来自分类Dev

如何在开玩笑的例外中进行测试

来自分类Dev

开玩笑-函数fs.writefile中的模拟回调

来自分类Dev

开玩笑:模拟构造函数

来自分类Dev

如何开玩笑模拟/间谍类的属性

来自分类Dev

开玩笑地测试DOM链中的属性更新

来自分类Dev

开玩笑:如何在node_modules中模拟库?

来自分类Dev

如何在子类对象的抽象类中访问私有属性的值?

来自分类Dev

如何在目标C中从超类重写私有方法和属性

来自分类Dev

如何生成在要测试的类中创建的模拟对象?

来自分类Dev

java - 如何在java中的被测类中注入被声明为私有静态的对象的模拟?

来自分类Dev

如何在 redux 中开玩笑地模拟异步动作创建者

来自分类Dev

如何在类中开玩笑地模拟节点模块?

Related 相关文章

  1. 1

    如何在Ruby中访问私有类方法?

  2. 2

    如何在单独的类中访问私有构造函数?

  3. 3

    如何在子类对象的抽象类中访问私有属性的值?

  4. 4

    如何在Scala中测试私有类方法?

  5. 5

    如何在目标C中从超类重写私有方法和属性

  6. 6

    C ++:如何在类中获取带有动态变量的私有属性?

  7. 7

    如何在C中模拟C ++中的私有成员变量?

  8. 8

    开玩笑-如何找到具有ID的渲染DOM组件?

  9. 9

    如何在RSpec中模拟我的超类

  10. 10

    如何在es6类中声明私有变量和私有方法

  11. 11

    如何在Python的类中模拟属性

  12. 12

    开玩笑预期在模拟vue-multiselect中的vuex操作上已调用了模拟功能

  13. 13

    如何模拟axios API调用?开玩笑

  14. 14

    如何在具有私有方法的Jest中模拟HTTP方法

  15. 15

    开玩笑抱怨错误...我告诉开玩笑期望

  16. 16

    开玩笑-模拟update()函数

  17. 17

    开玩笑的手动ES6类模拟未激活,我想了解为什么

  18. 18

    如何在开玩笑的例外中进行测试

  19. 19

    开玩笑-函数fs.writefile中的模拟回调

  20. 20

    开玩笑:模拟构造函数

  21. 21

    如何开玩笑模拟/间谍类的属性

  22. 22

    开玩笑地测试DOM链中的属性更新

  23. 23

    开玩笑:如何在node_modules中模拟库?

  24. 24

    如何在子类对象的抽象类中访问私有属性的值?

  25. 25

    如何在目标C中从超类重写私有方法和属性

  26. 26

    如何生成在要测试的类中创建的模拟对象?

  27. 27

    java - 如何在java中的被测类中注入被声明为私有静态的对象的模拟?

  28. 28

    如何在 redux 中开玩笑地模拟异步动作创建者

  29. 29

    如何在类中开玩笑地模拟节点模块?

热门标签

归档