【发布时间】:2022-01-04 12:55:57
【问题描述】:
我正在尝试为我使用 graphql 和 Apollo 的角度服务编写测试。
我收到这些错误:Error: Expected one matching operation for criteria "Match DocumentNode", found none.
和
Error: Expected no open operations, found 1:
fund-summary.service.spec.ts
import { TestBed } from '@angular/core/testing';
import {
ApolloTestingController,
ApolloTestingModule,
} from 'apollo-angular/testing';
import { FundSummaryService } from './fund-summary.service';
import { ConfigurationId, FundId, ShareClassCode } from '@types';
import { ApolloError, gql } from '@apollo/client/core';
import {
FundDataServiceParams,
ProductTypeParameter,
} from './graphql-fund-data.service';
import { DocumentNode, GraphQLError } from 'graphql';
import { SummaryDetail } from '@models';
import { MapperFactory } from '@products/utils/mappers/mapper-factory';
import { SiteConfigService } from '@services/site-config.service';
import { createMockSiteConfigService } from '@test/mock-site-config.service';
import { TranslateService } from '@shared/translate/translate.service';
import { HttpClientTestingModule } from '@angular/common/http/testing';
const fragment: DocumentNode = gql`
fragment SummaryDetails on SummaryDetails {
elemname
elemnamestd
elemvalue
sectionstd
section
sortorder
asofdate
}
`;
const summaryQuery: DocumentNode = gql`
query Summary(
$fundid: String!
$shareclasscode: String!
$countrycode: String!
$languagecode: String!
) {
Summary(
fundid: $fundid
shareclasscode: $shareclasscode
countrycode: $countrycode
languagecode: $languagecode
) {
...SummaryDetails
}
}
${fragment}
`;
const fundDataServiceParams: FundDataServiceParams = {
configurationName: ConfigurationId.MF,
productType: ProductTypeParameter.MUTUAL_FUNDS,
fundId: '21412' as FundId,
shareClassCode: 'SINGLCLASS' as ShareClassCode,
};
const expectedRawSummaryDetails: any = {
Summary: [
{
fundid: '21412',
shclcode: 'SINGLCLASS',
cntrycode: 'ZA',
langcode: 'en_GB',
sectionstd: 'Fund Information',
section: '',
elemnamestd: 'FACTOR_CATEGORY',
elemname: 'ETF Category',
elemvaluestd: 'Smart Beta',
elemvalue: 'Smart Beta',
preelemvaluestd: '',
preelemvalue: '',
sortorder: '25',
datedriven: 'No',
asofdate: '',
asofdatestd: '',
},
],
};
const expectedSummaryDetails: SummaryDetail[] = [
{
fundId: '21412',
shareClassCode: 'SINGLCLASS',
countryCode: 'ZA',
languageCode: 'en_GB',
sectionStd: 'Fund Information',
section: '',
elementNameStd: 'FACTOR_CATEGORY',
elementName: 'ETF Category',
elementValueStd: 'Smart Beta',
elementValue: 'Smart Beta',
preelemValueStd: '',
preelemValue: '',
sortOrder: '25',
dateDriven: 'No',
asOfDate: '',
asOfDateStd: '',
},
];
describe('FundSummaryServiceRegisterMethod', () => {
let controller: ApolloTestingController;
let fundSummaryService: FundSummaryService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ApolloTestingModule, HttpClientTestingModule],
providers: [
FundSummaryService,
TranslateService,
MapperFactory,
{ provide: SiteConfigService, useFactory: createMockSiteConfigService },
],
});
controller = TestBed.inject(ApolloTestingController);
fundSummaryService = TestBed.inject(FundSummaryService);
});
afterEach(() => {
controller.verify();
});
fit('should return summary details', (done: DoneFn) => {
fundSummaryService
.register(fragment, fundDataServiceParams)
.subscribe((mappedSummaryDetails) => {
expect(mappedSummaryDetails).toEqual(expectedSummaryDetails);
done();
});
const op = controller.expectOne(summaryQuery);
expect(op.operation.variables.fundid).toEqual(fundDataServiceParams.fundId); // same fund is resulted.
op.flushData(expectedRawSummaryDetails);
});
});
fund-summary.service.ts
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Logger } from '@utils/logger';
import { Apollo } from 'apollo-angular';
import { DocumentNode } from 'graphql';
import {
FundDataServiceParams,
GraphQLFundDataService,
} from './graphql-fund-data.service';
import { map } from 'rxjs/operators';
import { Product, SummaryDetail } from '@models';
import { MapperParams } from '@products/utils/mappers/type.mapper';
import { MapperFactory } from '@products/utils/mappers/mapper-factory';
import { SummaryDetailsMapper } from '@products/utils/mappers/summary-details.type.mapper';
import { SiteConfigService } from '@services/site-config.service';
import { ProductDTO, SummaryDetailDTO } from '@types';
import { TranslateService } from '@shared/translate/translate.service';
import { ProductMapper } from '@products/utils/mappers/product.type.mapper';
const logger = Logger.getLogger('FundSummaryService');
@Injectable({
providedIn: 'root',
})
export class FundSummaryService extends GraphQLFundDataService {
constructor(
apollo: Apollo,
siteConfigService: SiteConfigService,
private translateService: TranslateService,
private mapperFactory: MapperFactory
) {
super(apollo, siteConfigService);
}
public register(
query: DocumentNode,
fundDataServiceParams: FundDataServiceParams
): Observable<[Product, SummaryDetail[]]> {
return super.register(query, this.getVariables(fundDataServiceParams)).pipe(
map((rawSummaryDetails) => {
logger.debug('Summary details response: ', rawSummaryDetails);
const overviewDto: ProductDTO = rawSummaryDetails?.data?.Overview
? rawSummaryDetails?.data?.Overview
: null;
const overviewMapperParams: MapperParams = {
config: this.siteConfigService,
translateService: this.translateService,
includeSoftClosed: true,
};
const mappedOverview: Product = overviewDto
? this.mapperFactory
.createMapper(ProductMapper, overviewMapperParams)
.toDomain(overviewDto)
: null;
const summaryDetailsDto: SummaryDetailDTO[] = rawSummaryDetails?.data
?.Summary
? rawSummaryDetails.data.Summary
: [];
const summaryDetailsMapperParams: MapperParams = {
config: this.siteConfigService,
fundId: fundDataServiceParams.fundId,
translateService: this.translateService,
taxonomy: mappedOverview?.productTaxonomy,
};
const mappedSummaryDetails: SummaryDetail[] = this.mapperFactory
.createMapper(SummaryDetailsMapper, summaryDetailsMapperParams)
.toDomain(summaryDetailsDto);
return [mappedOverview, mappedSummaryDetails];
})
);
}
/**
* Return required variables value to graphql query.
* @param fundDataServiceParams params required for graphql query
*/
private getVariables(
fundDataServiceParams: FundDataServiceParams
): Record<string, any> {
return {
countrycode: this.getCountry(),
languagecode: this.getLanguage(),
fundid: fundDataServiceParams.fundId,
shareclasscode: fundDataServiceParams.shareClassCode,
};
}
}
注意:我试过这个old post's suggestion,没用。
【问题讨论】:
标签: angular graphql jasmine karma-jasmine apollo