如何在Angular中测试SCSS子类样式并设置只读属性car?
问题描述
需要测试Angular组件在不同环境(bmw、audi、vw)下的背景色切换功能:选中不同环境时,组件的span元素会动态添加对应CSS类,从而显示不同背景色。但组件中car是只读getter属性,无法直接设置component.car,纠结是添加setter函数还是修改注入的appConfig。
相关组件代码如下:
component.html
<span class="car-models {{ car }}">Welcome</span>
component.scss
.car-models { &.bmw{ background: blue; } &.audi { background: yellow; } &.vw { background: black; } }
component.ts
export class MyComponent implements OnInit { browserVersion = 'N/A'; hostName = 'N/A'; constructor( @Inject(APP_VERSION) public appConfig: { car?: string; appVersion?: string } ) {} get car(): string | undefined { return this.appConfig.car?.toLocaleLowerCase(); } }
现有测试代码(待完善)
beforeEach(() => { fixture = TestBed.createComponent(MyComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); it('check background color', () => { //if <span class="car-models bmw">Welcome</span> // than should the backgroundcolor of the text blue; // if <span class="car-models audi">Welcome</span> // than should the background color of the text yellow });
解决方案
最优方式是直接修改组件的appConfig属性,不需要额外编写setter函数——因为组件的car getter本身就是从appConfig.car派生的,直接修改源数据更贴合现有逻辑,也避免不必要的代码冗余。
修改后的测试用例如下:
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { MyComponent } from './my.component'; import { APP_VERSION } from './app-version.token'; // 确保导入你的token describe('MyComponent', () => { let fixture: ComponentFixture<MyComponent>; let component: MyComponent; let spanElement: HTMLElement; beforeEach(() => { TestBed.configureTestingModule({ declarations: [MyComponent], providers: [ { provide: APP_VERSION, useValue: { car: undefined, appVersion: '1.0.0' } } ] }); fixture = TestBed.createComponent(MyComponent); component = fixture.componentInstance; spanElement = fixture.nativeElement.querySelector('span'); }); it('should create', () => { expect(component).toBeTruthy(); }); it('should apply blue background when car is bmw', () => { // 设置appConfig的值 component.appConfig.car = 'BMW'; // 触发变更检测,更新视图 fixture.detectChanges(); // 验证CSS类是否正确添加 expect(spanElement.classList.contains('bmw')).toBeTrue(); // 验证背景色(注意getComputedStyle返回的是rgb格式,需对应转换) expect(getComputedStyle(spanElement).backgroundColor).toBe('rgb(0, 0, 255)'); }); it('should apply yellow background when car is audi', () => { component.appConfig.car = 'AUDI'; fixture.detectChanges(); expect(spanElement.classList.contains('audi')).toBeTrue(); expect(getComputedStyle(spanElement).backgroundColor).toBe('rgb(255, 255, 0)'); }); it('should apply black background when car is vw', () => { component.appConfig.car = 'VW'; fixture.detectChanges(); expect(spanElement.classList.contains('vw')).toBeTrue(); expect(getComputedStyle(spanElement).backgroundColor).toBe('rgb(0, 0, 0)'); }); });
关键说明
- 因为
appConfig在组件中是public属性,所以可以直接在测试用例中修改其car字段。 - 修改后必须调用
fixture.detectChanges()触发视图更新,这样动态绑定的CSS类才会生效。 - 使用
getComputedStyle获取实际渲染的样式时,注意浏览器返回的是RGB格式,需要和CSS中的颜色对应(比如blue对应rgb(0,0,255))。 - 如果
appConfig是不可变对象,也可以在每个测试用例中重新配置TestBed的APP_VERSION提供者,传入不同的car值。
内容的提问来源于stack exchange,提问作者Hasan Gümüş
相关产品推荐
相关产品推荐

