gpt4 book ai didi

typescript - 单例服务的 Angular 单元测试

转载 作者:行者123 更新时间:2023-12-04 03:45:03 34 4
gpt4 key购买 nike

我正在针对单例服务进行角度单元测试。我有一个在根模块中提供的 UserService 是应用程序中的单例,我想编写一个单元测试来检查 UserService 的实例在整个应用程序中是否相同。我可以做类似下面的事情,但它会检查组件和 Testbed 实例。有什么办法可以为所有功能模块编写一个单元测试来检查我们是否有相同的实例?感谢任何帮助。

import { TestBed, ComponentFixture, inject } from '@angular/core/testing';
import { LoginComponent } from './login.component';
import { AuthService } from "./auth.service";

class MockAuthService extends AuthService {
isAuthenticated() {
return 'Mocked';
}
}

describe('Component: Login', () => {

let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
let testBedService: AuthService;
let componentService: AuthService;

beforeEach(() => {

// refine the test module by declaring the test component
TestBed.configureTestingModule({
declarations: [LoginComponent],
providers: [AuthService]
});

// Configure the component with another set of Providers
TestBed.overrideComponent(
LoginComponent,
{ set: { providers: [{ provide: AuthService, useClass: MockAuthService }] } }
);

// create component and test fixture
fixture = TestBed.createComponent(LoginComponent);

// get test component from the fixture
component = fixture.componentInstance;

// AuthService provided to the TestBed
testBedService = TestBed.get(AuthService);

// AuthService provided by Component, (should return MockAuthService)
componentService = fixture.debugElement.injector.get(AuthService);
});

it('Service injected via inject(...) and TestBed.get(...) should be the same instance',
inject([AuthService], (injectService: AuthService) => {
expect(injectService).toBe(testBedService);
})
);

});

最佳答案

我觉得这属于“不测试框架”的大类。

如果您使用 @Injectable({ providedIn: 'root' }) 装饰器来装饰服务类型,您可以保证每个需要实例的组件或服务将获得相同的实例。从 Angular 6(或 5?我不记得了)开始,您通常不应该为模块中的服务添加 providers。使用 providedIn 的默认行为符合您的要求。请参阅此以供引用:https://angular.io/guide/providers .

每个提供的服务都作为单例解析的保证来自 Injector 的单元测试,原则上和实践上你都不应该保证:运行单元测试时你没有使用相同的依赖项注入(inject)基础设施比运行应用程序时!因此,您的测试将毫无意义:您将测试 TestBed,而不是运行时注入(inject)器。

并且您不能保证代码库中的某个人会添加一个{ provide: AuthService, useClass: AuthService } 并实例化另一个 AuthService。

我不知道您的确切要求,但是:

  • 如果您需要“知道”只构建了一个实例,请使用 providedIn: 'root',删除每个功能模块中的每个 provider,然后您可以开始了。默认行为符合您的要求。
  • 如果您希望更加确定每个应用程序只运行一个构造函数,并且您可以接受运行时错误(由于上述原因,您无法在编译时捕获它),您可以添加一个断言:
@Injectable({ providedIn: 'root' })
export class AuthService {
private static initialized = false;

constructor() {
if (isDevMode() && AuthService.initialized) {
throw new Error('AuthService: instance already initialized');
}

AuthService.initialized = true;
}

}

只是,不要对其进行单元测试。

关于typescript - 单例服务的 Angular 单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65319511/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com