Жасмин тест с выбором элементов из списка - PullRequest
0 голосов
/ 27 ноября 2018

У меня угловое приложение, и мне нужно провести модульное тестирование некоторых методов с помощью Jasmine.В этом случае я делаю модульное тестирование в списке выбора.Так что список выбора не будет пустым.

Метод выглядит так:

 createStatusOptions(listValueoptions: OptionModel[], resources: any): OptionModel[] {
        const processStatusOptions = listValueoptions.map(listValueOption => {
            listValueOption.value = `${caseStatusEnum.inProgress}_${listValueOption.value}`;
            listValueOption.selected = true;
            return listValueOption;
        });

        const caseStatusEnumKeys = Object.keys(caseStatusEnum).filter(key => !isNaN(Number(key)));
        const enumOptions = this.optionService.createOptions(
            new ConfigOptionModel({ source: caseStatusEnumKeys, resources, resourcesModel: enumResourcesModel, isCustomEnum: true, }));

        return [
            this.getEnumOption(enumOptions, caseStatusEnum.submitted, true),
            ...processStatusOptions,
            this.getEnumOption(enumOptions, caseStatusEnum.closed),
        ];
    }

 private getEnumOption(options: OptionModel[], enumType, isSelected = false): OptionModel {
        const option = options.filter(enumOption => enumOption.value === `${enumType}`)[0];
        option.selected = isSelected;
        return option;
    }

И у меня есть модульный тест, подобный этому:

it('should create status options when there ar list value options are provided', () => {
        optionService.options = [
            {
                value: caseStatusEnum.submitted.toString(),
            },
            {
                value: caseStatusEnum.inProgress.toString(),
            },
            {
                value: caseStatusEnum.closed.toString(),
            },
        ] as OptionModel[];



        // tslint:disable-next-line:max-line-length
        const result = service.createStatusOptions(optionService.options, [[103], [104], [105] ]);
        console.log(result);
       expect(result.length).toBe(2);
        expect(result).toEqual([{ value: '103', selected: true }, { value: '105', selected: false }]);

    });

НоЯ получаю сообщение об ошибке, подобное этому:

Services: CaseService > should create status options when there ar list value options are provided
TypeError: Cannot set property 'selected' of undefined
    at <Jasmine>
    at CaseService.getEnumOption (http://localhost:9878/src/app/case/src/services/case.service.ts?:130:9)
    at CaseService.getEnumOption [as createStatusOptions] (http://localhost:9878/src/app/case/src/services/case.service.ts?:109:22)
    at UserContext.<anonymous> (http://localhost:9878/src/app/case/src/services/case.service.spec.ts?:149:32)
    at ZoneDelegate.../../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9878/E:/Projects/Source/Repos/VLR/Web/vlrworkspace/node_modules/zone.js/dist/zone.js?:388:1)
    at ProxyZoneSpec.push.../../node_modules/zone.js/dist/proxy.js.ProxyZoneSpec.onInvoke (http://localhost:9878/E:/Projects/Source/Repos/VLR/Web/vlrworkspace/node_modules/zone.js/dist/proxy.js?:128:1)
    at ZoneDelegate.../../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9878/E:/Projects/Source/Repos/VLR/Web/vlrworkspace/node_modules/zone.js/dist/zone.js?:387:1)
    at Zone.../../node_modules/zone.js/dist/zone.js.Zone.run (http://localhost:9878/E:/Projects/Source/Repos/VLR/Web/vlrworkspace/node_modules/zone.js/dist/zone.js?:138:1)
    at runInTestZone (http://localhost:9878/E:/Projects/Source/Repos/VLR/Web/vlrworkspace/node_modules/zone.js/dist/jasmine-patch.js?:145:1)
    at UserContext.<anonymous> (http://localhost:9878/E:/Projects/Source/Repos/VLR/Web/vlrworkspace/node_modules/zone.js/dist/jasmine-patch.js?:160:1)
    at <Jasmine>

Итак, мой вопрос: как это решить?

Спасибо

, если я сделаю это:

   console.log(optionService.options);

Я получаю этот вывод:

Array(3)
0: {value: "103", selected: true}
1: {value: "104"}
2: {value: "105", selected: false}
length: 3
__proto__: Array(0)

это файл:

import { fakeAsync, tick } from '@angular/core/testing';
import { FormServiceMock, MultiFileUploadServiceMock } from 'afw/forms/testing';
import { AfwHttp } from 'afw/generic-services';
import { AfwHttpMock, OptionServiceMock } from 'afw/generic-services/testing';
import { OptionModel, SearchResultModel } from 'afw/models';
import { FeedbackStoreServiceMock } from 'afw/store-services/testing';
import { RouterMock } from 'afw/testing';
import { PagingDataModel, TableSortDataModel } from 'afw/ui-components';
import { caseOwnerEnum, caseStatusEnum, caseTypeEnum, MultiFileUploadResourcesModel } from 'lr/models';
import { Observable, observable } from 'rxjs';
import { CaseTypeInfoModel } from 'support-shared/base/models';
import { CaseTypeInfoStoreServiceMock } from 'support-shared/base/services/case-type-info-store.service.mock';
import { CaseFormComponent } from '../case-base/src/case-form/case-form.component';
import { CaseBaseModel, CaseReferenceModel } from '../models';
import { CaseService } from './case.service';

let service: CaseService;
let afwHttpMock: AfwHttpMock;
// tslint:disable-next-line:prefer-const
let formServiceMock: FormServiceMock;
let multiFileUploadService: MultiFileUploadServiceMock;
let router: RouterMock;
let feedbackStoreService: FeedbackStoreServiceMock;
let optionService: OptionServiceMock;
let caseTypeInfoStoreService: CaseTypeInfoStoreServiceMock;
// tslint:disable-next-line:prefer-const
let component: CaseFormComponent;


fdescribe('Services: CaseService', () => {

    beforeEach(() => {
        afwHttpMock = new AfwHttpMock();
        multiFileUploadService = new MultiFileUploadServiceMock();
        router = new RouterMock();
        feedbackStoreService = new FeedbackStoreServiceMock();
        optionService = new OptionServiceMock();
        caseTypeInfoStoreService = new CaseTypeInfoStoreServiceMock();
        service = new CaseService(afwHttpMock as any, multiFileUploadService as any, router as any,
            feedbackStoreService as any, optionService as any, caseTypeInfoStoreService as any);
    });

    it('should create an instance', () => {
        expect(service).toBeTruthy();
    });

    it('should get case reference details', () => {
        afwHttpMock.setupOnlyResponse({ type: caseTypeEnum.revisionRequest, details: { bsn: 'bsnLabel' } }, 200);
        const d = service.getCaseReferenceDetails('spinnerMessage', { reference: '112314121', type: caseTypeEnum.revisionRequest });
        d.subscribe(r => {
            expect(r.details.length === 1);
            expect(r.details[0].key).toBe('bsn');
            expect(r.details[0].value).toBe('bsnLabel');
            expect((r.details[0] as any).resourceKey).toBe('bsn');
        });
        afwHttpMock.returnSuccessResponse();
    });


    // tslint:disable-next-line:no-identical-functions
    it('should get case reference details with full response', () => {
        afwHttpMock.setupOnlyResponse({ body: { type: caseTypeEnum.revisionRequest, details: [{ key: 'hoi' }] } }, 200);
        const d = service.getCaseReferenceDetailsFullResponse('spinnerMessage', { reference: '100001075', type: caseTypeEnum.revisionRequest });
        // tslint:disable-next-line:no-commented-code
        // tslint:disable-next-line:no-identical-functions
        /*  let result;
         d.subscribe(r => {
             result = r;
         }); */

        d.subscribe(r => {
            expect(r.ok === true);
            expect(r.body.details[0].key).toBe('hoi');
        });

        afwHttpMock.returnSuccessResponse();
        // expect(result.ok === true);
        // expect(result.)

    });


    // tslint:disable-next-line:no-commented-code
    it('shoud get case type info configuration that is used on various views when snapshot exists', () => {
        let result99: Observable<CaseTypeInfoModel[]>;
        result99 = service.getCaseTypeInfo('spinner') as Observable<CaseTypeInfoModel[]>;
        const response = [{ mock: 'mock' } as any];
        service['caseTypeInfoSnapshot'] = response;
        service.getCaseTypeInfo('spinner').subscribe(i => {
            expect(i).toEqual(response);
        });
    });

    // tslint:disable-next-line:no-identical-functions
    it('shoud get case type info configuration that is used on various views when snapshot doesnt exists', () => {
        let result99: Observable<CaseTypeInfoModel[]>;
        const spy = spyOn(caseTypeInfoStoreService, 'addCaseTypeInfoToStore');
        result99 = service.getCaseTypeInfo('spinner') as Observable<CaseTypeInfoModel[]>;
        const response = [{ mock: 'mock' } as any];
        service['caseTypeInfoSnapshot'] = response;
        // caseTypeInfoStoreService..subscribe((result) => { expect(result).toBe(false); });
        result99.subscribe((result) => {
            expect(response).toEqual(response);
        });


        afwHttpMock.setupOnlyResponse(result99, 200);
        afwHttpMock.returnSuccessResponse();
    });

    it('should create status options when no list value options are provided', () => {
        optionService.options = [
            {
                value: caseStatusEnum.submitted.toString(),
            },
            {
                value: caseStatusEnum.inProgress.toString(),
            },
            {
                value: caseStatusEnum.closed.toString(),
            },
        ] as OptionModel[];


        // tslint:disable-next-line:no-commented-code
        //  const spy = spyOn(service, 'createStatusOptions');
        const result = service.createStatusOptions([], {});
        expect(result.length).toBe(2);
        expect(result).toEqual([{ value: '103', selected: true }, { value: '105', selected: false }]);
        // tslint:disable-next-line:no-commented-code
        //  const response = [{ mock: 'mock' } as any];
        // expect(spy).toBe(result);
    });

    it('should create status options when there ar list value options are provided', () => {
        optionService.options = [
            {
                value: caseStatusEnum.submitted.toString(),
            },
            {
                value: caseStatusEnum.inProgress.toString(),
            },
            {
                value: caseStatusEnum.closed.toString(),
            },
        ] as OptionModel[];



        // tslint:disable-next-line:max-line-length
        const result = service.createStatusOptions(optionService.options, 103);
        console.log(optionService.options);
        expect(result.length).toBe(2);
        expect(result).toEqual([{ value: '103', selected: true }, { value: '105', selected: false }]);

    });






    it('should get case reference without details', () => {
        afwHttpMock.setupOnlyResponse({}, 200);
        const spy = spyOn(afwHttpMock, 'post').and.callThrough();
        const model = new CaseReferenceModel({ reference: '112314121', type: caseTypeEnum.revisionRequest });
        const d = service.getCaseReferenceDetails('spinnerMessage', model);
        d.subscribe(r => {
            expect(r).toBeDefined();
        });
        expect(spy).toHaveBeenCalledWith('api/support/cases/get-reference-details', model, 'spinnerMessage');
        afwHttpMock.returnSuccessResponse();
    });

    it('should add case reference without details', () => {
        afwHttpMock.setupOnlyResponse({}, 200);
        const spy = spyOn(afwHttpMock, 'post').and.callThrough();
        const model = new CaseReferenceModel({ reference: '112314121', type: caseTypeEnum.revisionRequest });
        const d = service.addCase('spinnerMessage', model as any);
        d.subscribe(r => {
            expect(r).toBeDefined();
        });
        expect(spy).toHaveBeenCalledWith('api/support/cases', model, 'spinnerMessage');
        afwHttpMock.returnSuccessResponse();
    });

    it('should search for cases', () => {
        const formModel: any = { makeQueryString: () => 'name=test' };
        const pagingModel = new PagingDataModel({ currentPage: 10, itemsPerPage: 20 });
        const sortModel = new TableSortDataModel({ columnName: 'kol', isDescending: false });

        const spy = spyOn(afwHttpMock, 'get').and.callThrough();
        const mockData = [
            new CaseBaseModel({
                id: 100000001,
                type: caseTypeEnum.revisionRequest,
                status: caseStatusEnum.inProgress,
                substatus: 5266,
                verdict: null,
                owner: caseOwnerEnum.caseManager,
                dateSubmitted: '02-02-2009',
                dateClosed: '',
                reference: 'aaa',
            }),
        ];

        const setupResponse = new SearchResultModel<CaseBaseModel>();
        setupResponse.result = mockData;
        setupResponse.totalResultCount = 27;

        afwHttpMock.setupOnlyResponse(setupResponse, 200);
        let response: SearchResultModel<CaseBaseModel>;
        service.search(formModel, sortModel, pagingModel, 'spinnerText').subscribe(result => {
            response = result;
        });
        afwHttpMock.returnOnlyResponse();

        expect(spy).toHaveBeenCalledWith('api/support/cases?name=test&columnName=kol&isDescending=false&currentPage=10&itemsPerPage=20',
            'spinnerText');
        expect(response).toEqual(setupResponse);
        expect(response.result[0].getResourceForStatus).toBeDefined();
    });

    it('should save documents', fakeAsync(() => {
        const spy = spyOn(multiFileUploadService, 'syncFilesWithBackend').and.callThrough();
        const spyRouter = spyOn(router, 'navigate').and.callThrough();
        const spyFeedback = spyOn(feedbackStoreService, 'addSuccessMessageOnMainPortal');
        service.saveDocuments(1, [{} as any], MultiFileUploadResourcesModel.keys, '../', { key: 'da', value: 'fa' });
        expect(spy).toHaveBeenCalledWith('api/support/cases/1/documents', [{}],
            MultiFileUploadResourcesModel.keys.bijlageToevoegenSpinnerTekst,
            MultiFileUploadResourcesModel.keys.bijlageVerwijderenSpinnerTekst
        );
        tick();
        expect(spyRouter).toHaveBeenCalledWith(['../']);
        expect(spyFeedback).toHaveBeenCalled();
    }));

    it('should not save documents if there are no documents in array', fakeAsync(() => {
        const spy = spyOn(multiFileUploadService, 'syncFilesWithBackend').and.callThrough();
        const spyRouter = spyOn(router, 'navigate').and.callThrough();
        const spyFeedback = spyOn(feedbackStoreService, 'addSuccessMessageOnMainPortal');
        service.saveDocuments(1, [], MultiFileUploadResourcesModel.keys, '../', { key: 'da', value: 'fa' });
        expect(spy).not.toHaveBeenCalled();
        tick();
        expect(spyRouter).toHaveBeenCalledWith(['../']);
        expect(spyFeedback).toHaveBeenCalled();
    }));

    it('should save documents and report errors', fakeAsync(() => {
        multiFileUploadService.setResponse([{}, { error: {} }]);
        spyOn(multiFileUploadService, 'makeWarningMessageForUnsyncedFiles').and.returnValue('mock');
        const spyRouter = spyOn(router, 'navigate').and.callThrough();
        const spyFeedback = spyOn(feedbackStoreService, 'addWarningMessageOnMainPortal');
        const spy = spyOn(multiFileUploadService, 'syncFilesWithBackend').and.callThrough();
        service.saveDocuments(1, [{} as any], MultiFileUploadResourcesModel.keys, '../', { key: 'da', value: 'fa' });
        expect(spy).toHaveBeenCalledWith('api/support/cases/1/documents', [{}],
            MultiFileUploadResourcesModel.keys.bijlageToevoegenSpinnerTekst,
            MultiFileUploadResourcesModel.keys.bijlageVerwijderenSpinnerTekst
        );
        tick();
        expect(spyRouter).toHaveBeenCalledWith(['../']);
        expect(spyFeedback).toHaveBeenCalled();
    }));


    it('should get case by id', () => {
        const id = 66208014;
        const setupResponse = new CaseBaseModel({
            id,
            dateSubmitted: '',
            owner: caseOwnerEnum.caseManager,
            reference: 'ksjhkjshdf',
            status: caseStatusEnum.submitted,
            type: caseTypeEnum.revisionRequest,

        });
        afwHttpMock.setupOnlyResponse(setupResponse, 200);
        service.getCase(id, 'spinner').subscribe(r => {
            expect(r).toEqual(setupResponse);
        });
        afwHttpMock.returnSuccessResponse();
    });

    it('edit the case with model', () => {
        const spy = spyOn(service, 'editCase').and.callThrough();

        const caseUpdate = new CaseBaseModel({
            id: 100001075,
            dateSubmitted: '',
            owner: caseOwnerEnum.caseManager,
            reference: 'ksjhkjshdf',
            status: caseStatusEnum.submitted,
            type: caseTypeEnum.revisionRequest,

        });
        service.editCase('spinner', caseUpdate);
        expect(spy).toHaveBeenCalledWith('spinner', caseUpdate);
        expect(caseUpdate.id).toEqual(100001075);
    });
});

1 Ответ

0 голосов
/ 27 ноября 2018

Исходя из того, что вы показали до сих пор, я предполагаю, что параметр options, переданный в getEnumOption(), не определен, что вызывает ошибку, которую вы видите.Быстрый console.log(options) в getEnumOption () подтвердит это.

Если в противном случае ваш код работает нормально, но только с ошибкой в ​​тесте, я бы сделал второе предположение, что вы не правильно смоделировали / spiedOn this.optionService.createOptions(), поскольку он устанавливает параметр options, который потенциально не определен,Это было бы сделано ранее в файле .spec - если вы опубликуете весь файл, то это поможет другим, прочитавшим ваш вопрос, определить, так ли это.

Обновление с помощью Stackblitz

Я положил весь ваш код в Stackblitz , чтобы проверить его.Было много кода, к которому у меня не было доступа, о котором я только догадывался по функциональности.Однако я обнаружил несколько вещей.

Во-первых, когда вы тестируете, вы, похоже, используете одну и ту же переменную как для макета возврата, ожидаемого this.optionService.createOptions(), так и для вызова * 1016.* - что, вероятно, не то, что вы хотите сделать.

Вот фрагмент кода, о котором я говорю:

optionService.options = [
    {
        value: caseStatusEnum.submitted.toString(),
    },
    {
        value: caseStatusEnum.inProgress.toString(),
    },
    {
        value: caseStatusEnum.closed.toString(),
    },
] as OptionModel[];

// tslint:disable-next-line:max-line-length
const result = service.createStatusOptions(optionService.options, [[103], [104], [105] ]);

Когда я назвал это так в Stackblitz, я столкнулся с проблемой изменчивости - вы меняете данные внутри членовобъекты внутри массива, которые изменят его, когда к этой переменной обращаются.Чтобы преодолеть это в Stackblitz, я сделал две копии данных, одну для использования в фиктивном returnValue, а другую - совершенно отдельный массив объектов для вызова service.createStatusOptions().Кроме того, я не знаком с тем, как вы издеваетесь над своим сервисным вызовом, поэтому я заменил его простым шпионом Жасмин в Stackblitz.

Не стесняйтесь взглянуть на то, что я произвел.Возможно, это будет полезно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...