错误:<spyOnProperty>:函数未声明为可配置

问题描述 投票:0回答:5

我使用 webpack 3 进行了 jasmine 测试。现在我尝试将其与 webpack 4 一起使用,但遇到了一些问题。

首先我遇到了spyOn功能的问题。

错误::myFunction 未声明为可写或没有设置器

我找到了一些关于此问题的解决方法的文章:spy-on-getter-and-setter

我将 spyOn 更改为 spyOnProperty 但没有运气。现在我遇到了问题

> 错误::myFunction 未声明为可配置

我的代码是用js编写的,如下所示:

import * as FocusServiceSpy from '../focus/FocusService';

describe('#onLinkClick', function() {
            it('should call myFunction', () => {
                spyOnProperty(FocusServiceSpy, 'myFunction', 'get');
                expect(FocusServiceSpy.myFunction).toHaveBeenCalled();
            });

        }

你知道这可能是什么问题吗?

更新1:

我应该更具描述性。我想创建监视 FocusService 的功能。该服务只有一种名为 myFunction 的方法。我唯一想要实现的就是确保这个方法会被调用。

现在我把它改成这样并且有错误:

>TypeError:对象不是构造函数(评估“new FocusService()”)(第 180 行)

describe('#onLinkClick', function() {
        const FocusService = require('../focus/FocusService');

        it('should call myFunction', () => {
            const service = new FocusService();
            spyOnProperty(service, 'myFunction').and.callThrough();
            ... (do some action)
            expect(service.myFunction).toHaveBeenCalled();
        });

    }

FocusService 看起来像这样:

export function myFunction(arg) {
    ... (do some action)
}
javascript angularjs jasmine webpack-4 spy
5个回答
7
投票

在你的单元测试中,我可以看到几个问题。首先,您需要了解

spyOnProperty
将属性上的
spy
安装到现有对象上,但它不会调用
getter
本身。

  1. 您不创建对象也不将其提供给

    spyOnProperty

  2. 您使用函数名称而不是属性来调用

    spyOnProperty
    名字。

您的测试可以按如下方式构建:

it('should call myFunction', () => {

    // given
    const service = new FocusService(); 
    const spy = spyOnProperty(service , 'myProperty', 'get').and.callThrough();

    // when
    const myProperty = service.myProperty; 

    // then
    expect(myProperty).toBe(<expected value>);
    expect(spy).toHaveBeenCalled();
});

2
投票

当我尝试将项目从 Angular 8 升级到 9 时,我遇到了同样的问题,我在 Google 上找不到答案,但是我找到了一种在我的项目中解决它的方法。

tsconfig.json
中,将
target
更改为
es5

示例:

{
  "compilerOptions": {
    ...
    "target": "es5",
    ...
  }
}

就是这样!希望这可以帮助正在尝试找到解决方案的人。


1
投票

在新版本的 Jasmine 中,不允许间谍变异,并且会为您尝试修改的间谍成员抛出上述错误。

不建议更改间谍属性的定义,因为 Jasmine 明确不允许成员可配置。

如果您不希望强制执行此限制,请将以下代码添加到您的入口测试文件中

const defineProperty = Object.defineProperty;
Object.defineProperty = (o, p, c) => defineProperty(o, p, Object.assign({}, c ?? {}, { configurable: true }));

上面的代码强制将测试运行期间定义的每个属性标记为可配置。


0
投票

在类定义文件中的导入之后添加

configure({ safeDescriptors: false });
,它可以与属性一起使用


0
投票

定义一个

spyHack
实用函数,暂时覆盖
Object.defineProperty
函数。

export class JasminHelper {
    public spyHack(doSpying: Function): void {
        const defineProperty = Object.defineProperty
        Object.defineProperty = (o, p, d) => defineProperty(o, p, { ...(d || {}), configurable: false })
        doSpying();
        Object.defineProperty = defineProperty;
    }
}

按如下方式调用

spyOnProperty

it('should call myFunction', () => {
    JasminHelper.spyHack(() => {
        spyOnProperty(FocusServiceSpy, 'myFunction', 'get');
    });
    expect(FocusServiceSpy.myFunction).toHaveBeenCalled();
});

基于Rudi的回答

© www.soinside.com 2019 - 2024. All rights reserved.