Jasmine 单元测试,仅在服务中覆盖 属性

Jasmine Unit Test, override only property in service

这是我的组件规范文件。它使用日历服务。在 CalendarService 内部有 weekNames、monthNames、monthLongNames 属性(它们只是字符串数组)。现在... CalendarService 里面有很多方法。我希望能够仅覆盖我的规范文件中的这 3 个属性,但保留其余方法并在规范文件中使用它们。我想覆盖它们的原因是因为它们使用另一个服务来创建(例如 weekNames = [this.translationService.formatMessage(), ... , ... , ...])。 这使得测试具有内部服务的组件变得非常困难。

编辑: 或者另一种解决方案是用模拟服务覆盖翻译服务。但是,translationservice 位于使用我的组件的 CalendarService 中。所以我不知道该怎么做。

describe('FCCalendarComponent', () => {
    let component: CalendarWrapperComponent;
    let fixture: ComponentFixture<CalendarWrapperComponent>;

    let calendarComponent: FCCalendarComponent;

    beforeEach(waitForAsync(() => {
        TestBed.configureTestingModule({
            declarations: [
                FCCalendarComponent,
                CalendarWrapperComponent
            ],
            imports: [
                BrowserModule,
                FormsModule,
                ReactiveFormsModule,
                FCBaseModule,
                HttpClientModule,
                FCTranslateModule,
                FCCalendarModule
            ],
            providers: [
                FCTranslateLoader,
                CalendarService,
                FCTranslationService,
                {
                    provider: CalendarService, useValue: {
                        weekNames: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
                        monthNames: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
                        monthLongNames: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
                    }
                },
            ]
        }).compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(CalendarWrapperComponent);
        component = fixture.componentInstance;
        calendarComponent = fixture.debugElement.children[0].componentInstance;
        fixture.detectChanges();
    })


    it('should create component', () => {
        expect(component).toBeTruthy();
    });
});



@Component({
    selector: 'calendar-wrapper',
    template: `
        <fc-calendar value="2001.02.02" 
            minDate="2000.03.03" 
            maxDate="2002.04.04">
        </fc-calendar>
    `
})
export class CalendarWrapperComponent {

}

覆盖三个属性(如您所展示的)或模拟翻译服务是一个合法的解决方案。

翻译服务不是“位于”日历服务内,而是注入其中。因此,为了模拟它,您需要使用 provide+useValue 机制,就像您对三个属性所做的那样(也许您必须创建 translationMockService class 并调用 useClass 而不是 useValue)。

解决方案: 如果您的组件中有一个服务,并且该服务内部使用了另一个服务。您可以模拟 'child' 服务,而不是模拟 'parent' 服务。 只需将 'child' 服务添加到像这样的提供商

FCTranslationService,
{
    provider: FCTranslationService, useValue: { }
},

并在 beforEach 中用您的模拟服务覆盖它,就像这样

TestBed.overrideProvider(FCTranslationService, { useValue: new TranslateMockService() })

如果你想知道 mock 是什么样子的。

export class TranslateMockService {
    formatMessage() {
        return;
    }
}

模拟只有父服务正在使用的方法,没有其他任何东西。