如何模拟模拟服务的 getter 参数值

Gab*_*iel 7 unit-testing mocking jasmine typescript angular

我已经尝试过这个SO,但这不是我的情况。

我有一个服务 ( AnimationService),它依赖于另一个服务 ( AnimationStateService)。它AnimationStateService有一个 getter state,我想在测试中模拟它。所以我的测试看起来像这样:

动画.服务.规格.ts

describe("AnimationService", () => {

let animationService: SpyObj<AnimationService>;
let animationStateService: SpyObj<AnimationStateService>;

beforeEach(() => {

    const spyAnimationStateService = createSpyObj("AnimationStateService", ["changeStatus"]);

    TestBed.configureTestingModule({
        providers: [
            AnimationService,
            {provide: AnimationStateService, useValue: spyAnimationStateService}
        ]
    });

    animationStateService = TestBed.get(AnimationStateService);
    animationService = TestBed.get(AnimationService);
});

fit("should call changeStatus if status is AnimationStatus.Stopped", () => {
    // Arrange
    // animationStateService.status.and.returnValue(AnimationStatus.Stopped); - Doesn't work
    // spyOnProperty(animationStateService, "status").and.returnValue(AnimationStatus.Stopped); - Doesn't work
    // animationStateService.status = AnimationStatus.Stopped; - Works, but with TSLint error

    // Act
    animationService.start();

    // Assert
    expect(animationStateService.changeStatus).toHaveBeenCalled();
   });
});
Run Code Online (Sandbox Code Playgroud)

动画状态.service.spec.ts

@Injectable()
export class AnimationStateService {

public get status(): AnimationStatus { return this.state.animation.status; }
...
}
Run Code Online (Sandbox Code Playgroud)

当我尝试用以下方法来模拟 getter 时:

animationStateService.status.and.returnValue(AnimationStatus.Stopped);
Run Code Online (Sandbox Code Playgroud)

或与:

spyOnProperty(animationStateService, "status").and.returnValue(AnimationStatus.Stopped);
Run Code Online (Sandbox Code Playgroud)

它不起作用。getter 根本不返回我设置的值。

这种方法有效:

animationStateService.status = AnimationStatus.Stopped;
Run Code Online (Sandbox Code Playgroud)

但它给了我一个 TSLint 错误:

Cannot assign to 'status' because it is a constant or a read-only property.
Run Code Online (Sandbox Code Playgroud)

所以现在我不知道,我还应该尝试什么来正确且没有错误地模拟吸气剂。

sli*_*wp2 4

您应该使用spyOnProperty(obj, propertyName, accessTypeopt) \xe2\x86\x92 {Spy}和第三个accessType参数来将间谍安装到getter方法上。

\n

例如

\n

animation.service.ts:

\n
import { Injectable } from \'@angular/core\';\nimport { AnimationStateService } from \'./animation-state.service\';\n\n@Injectable()\nexport class AnimationService {\n  constructor(private animationStateService: AnimationStateService) {}\n  start() {\n    return this.animationStateService.status;\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

animation-state.service.ts:

\n
import { Injectable } from \'@angular/core\';\n\nexport enum AnimationStatus {\n  Stopped = \'Stopped\',\n  Started = \'Started\',\n}\n\n@Injectable()\nexport class AnimationStateService {\n  state = {\n    animation: {\n      status: AnimationStatus.Started,\n    },\n  };\n  public get status(): AnimationStatus {\n    return this.state.animation.status;\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

animation.service.spec.ts:

\n
import { TestBed } from \'@angular/core/testing\';\nimport {\n  AnimationStateService,\n  AnimationStatus,\n} from \'./animation-state.service\';\nimport { AnimationService } from \'./animation.service\';\n\nfdescribe(\'53333050\', () => {\n  let animationStateService: AnimationStateService;\n  let animationService: AnimationService;\n\n  beforeEach(() => {\n    TestBed.configureTestingModule({\n      providers: [AnimationService, AnimationStateService],\n    });\n\n    animationStateService = TestBed.get(AnimationStateService);\n    animationService = TestBed.get(AnimationService);\n  });\n\n  it(\'should call changeStatus if status is AnimationStatus.Stopped\', () => {\n    // Arrange\n    const statusGetterSpy = spyOnProperty(\n      animationStateService,\n      \'status\',\n      \'get\'\n    ).and.returnValue(AnimationStatus.Stopped);\n\n    // Act\n    const actual = animationService.start();\n    expect(actual).toEqual(AnimationStatus.Stopped);\n\n    // Assert\n    expect(statusGetterSpy).toHaveBeenCalled();\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n

单元测试结果:

\n

在此输入图像描述

\n