1

ロジックを含む Angular サービスをテストしたいと考えています。簡単にするために、ケースを単純化します。

テストしたい logic$ があります。これは data$ にバインドされており、別のオブザーバブルです

@Injectable({
    providedIn: 'root',
})
export class MyService {
    readonly data = new BehaviorSubject<string>('');
    readonly data$ = this.data.asObservable();

    readonly logic$ = this.data$.pipe(
        map((logic: string) => `Mighty ${logic}`)
    )

    constructor() {}
}

テストでデータをモックして、ロジックが意図したとおりに動作しているかどうかを確認したい

describe('MyService', () => {
    let myService: MyService;

    const testScheduler = new TestScheduler((actual, expected) => {
        expect(actual).toEqual(expected);
    });

    beforeEach(() => {
        myService = new MyService();
        myService.data$ = of("foo", "bar");
        TestBed.configureTestingModule({
            providers: [{ provide: MyService, useValue: myService }]
        });
    });

    it('should be created', inject([MyService], (service: MyService) => {
        expect(service).toBeTruthy();
    }));

    it('should be toto lala', inject([MyService], (service: MyService) => {
        testScheduler.run(helpers => {
            const { expectObservable, cold } = helpers;
            const expect$ = "ab";
            expectObservable(service.logic$).toBe(expect$, {
                a: "Mighty foo",
                b: "Mighty bar",
            })
        });
    }));
});

次のエラーが表示されます。

    Chrome Headless 97.0.4692.99 (Windows 10) MyService should be toto lala FAILED
            Expected $.length = 1 to equal 2.
            Expected $[0].notification.value = 'Mighty ' to equal 'Mighty foo'.
            Expected $[1] = undefined to equal Object({ frame: 1, notification: Notification({ kind: 'N', value: 'Mighty bar', error: undefined, hasValue: true }) }).
            Error: Expected $.length = 1 to equal 2.
            Expected $[0].notification.value = 'Mighty ' to equal 'Mighty foo'.
            Expected $[1] = undefined to equal Object({ frame: 1, notification: Notification({ kind: 'N', value: 'Mighty bar', error: undefined, hasValue: true }) }).
                at <Jasmine>
                at TestScheduler.assertDeepEqual (projects/ui-affaire-client/src/lib/components/my-component/my-component.service.spec.ts:11:20)
                at node_modules/rxjs/_esm2015/internal/testing/TestScheduler.js:110:1
                at <Jasmine>
    Chrome Headless 97.0.4692.99 (Windows 10): Executed 2 of 3 (1 FAILED) (0 secs / 0.028 secs)
    Chrome Headless 97.0.4692.99 (Windows 10) MyService should be toto lala FAILED
            Expected $.length = 1 to equal 2.
            Expected $[0].notification.value = 'Mighty ' to equal 'Mighty foo'.
            Expected $[1] = undefined to equal Object({ frame: 1, notification: Notification({ kind: 'N', value: 'Mighty bar', error: undefined, hasValue: true }) }).
            Error: Expected $.length = 1 to equal 2.
            Expected $[0].notification.value = 'Mighty ' to equal 'Mighty foo'.
            Expected $[1] = undefined to equal Object({ frame: 1, notification: Notification({ kind: 'N', value: 'Mighty bar', error: undefined, hasValue: true }) }).
                at <Jasmine>
                at TestScheduler.assertDeepEqual (projects/ui-affaire-client/src/lib/components/my-component/my-component.service.spec.ts:11:20)
                at node_modules/rxjs/_esm2015/internal/testing/TestScheduler.js:110:1
    Chrome 97.0.4692.99 (Windows 10) MyService should be toto lala FAILED
            Expected $.length = 1 to equal 2.
            Expected $[0].notification.value = 'Mighty ' to equal 'Mighty foo'.
            Expected $[1] = undefined to equal Object({ frame: 1, notification: Notification({ kind: 'N', value: 'Mighty bar', error: undefined, hasValue: true }) }).
            Error: Expected $.length = 1 to equal 2.
            Expected $[0].notification.value = 'Mighty ' to equal 'Mighty foo'.
            Expected $[1] = undefined to equal Object({ frame: 1, notification: Notification({ kind: 'N', value: 'Mighty bar', error: undefined, hasValue: true }) }).
                at <Jasmine>
                at TestScheduler.assertDeepEqual (projects/ui-affaire-client/src/lib/components/my-component/my-component.service.spec.ts:11:20)
                at node_modules/rxjs/_esm2015/internal/testing/TestScheduler.js:110:1
                at <Jasmine>
    Chrome Headless 97.0.4692.99 (Windows 10): Executed 2 of 3 (1 FAILED) (skipped 1) (0.097 secs / 0.028 secs)
    Chrome 97.0.4692.99 (Windows 10): Executed 1 of 3 (1 FAILED) (0 secs / 0.019 secs)
    Chrome 97.0.4692.99 (Windows 10) MyService should be toto lala FAILED
            Expected $.length = 1 to equal 2.
            Expected $[0].notification.value = 'Mighty ' to equal 'Mighty foo'.
            Expected $[1] = undefined to equal Object({ frame: 1, notification: Notification({ kind: 'N', value: 'Mighty bar', error: undefined, hasValue: true }) }).
            Error: Expected $.length = 1 to equal 2.
            Expected $[0].notification.value = 'Mighty ' to equal 'Mighty foo'.
            Expected $[1] = undefined to equal Object({ frame: 1, notification: Notification({ kind: 'N', value: 'Mighty bar', error: undefined, hasValue: true }) }).
                at <Jasmine>
                at TestScheduler.assertDeepEqual (projects/ui-affaire-client/src/lib/components/my-component/my-component.service.spec.ts:11:20)
    Chrome Headless 97.0.4692.99 (Windows 10): Executed 2 of 3 (1 FAILED) (skipped 1) (0.097 secs / 0.028 secs)
    Chrome 97.0.4692.99 (Windows 10): Executed 2 of 3 (1 FAILED) (skipped 1) (0.099 secs / 0.026 secs)
    TOTAL: 2 FAILED, 2 SUCCESS
    TOTAL: 2 FAILED, 2 SUCCESS

私が理解できることは、目に見えて私のモックが機能していないことです。logic$ の長さは 1 で、データは '' (behaviorSubject によって発行されます) のみを発行します。私の推測では、サービスの作成後にモックが完了したため、「古い」オブザーバブルは引き続き使用され、置き換えられません。 .

オブザーバブルを適切に置き換えてサービスのロジックをテストする方法はありますか?

4

1 に答える 1