การเยาะเย้ยคุณสมบัติหัวเรื่องของบริการจำลองที่จะสมัครในการทดสอบหน่วยเชิงมุม
ในหน่วยเชิงมุมของฉันการทดสอบบริการจำลองของฉันมีคุณสมบัติสองประการ:
public messageChange: Subject<ChatMessage> = new Subject<ChatMessage>();
public gameChange: Subject<GameState> = new Subject<GameState>();
และใน SUT ของฉันฉันใช้มันในตัวสร้างของฉัน:
this._subChat = this.hub.messageChange.subscribe((message: ChatMessage) => {
this.message = message;
this.messageChange.next(this.message);
});
this._subGame = this.hub.gameChange.subscribe((game: GameState) => {
this.game.setGame(game);
});
ตอนนี้ฉันกำลังพยายามใช้ 2 วิธีนี้เพื่อจำลองคุณสมบัติจากบริการจำลอง:
- Angular Unit Test Mock Replay Subject
- วิธีการสอดแนมบนทรัพย์สินมูลค่า (แทนที่จะเป็นวิธีการ) ด้วยจัสมิน
Riht ตอนนี้การทดสอบของฉันมีลักษณะดังนี้:
describe('SignalRService', () => {
let signalrService: SignalRService;
const hubServiceMock = jasmine.createSpyObj('HubConnectionService', [
'isConnectionStarted',
]);
const messageChange = new Subject();
const gameChange = new Subject();
beforeEach(() => {
signalrService = new SignalRService(
hubServiceMock
);
let msg = {} as ChatMessage;
let gam = {} as GameState;
messageChange.next(msg);
gameChange.next(gam);
});
it('Service_ShouldBeCreated', () => {
spyOnProperty(hubServiceMock, 'messageChange', 'get').and.returnValue(
messageChange
);
spyOnProperty(hubServiceMock, 'gameChange', 'get').and.returnValue(
gameChange
);
expect(signalrService).toBeTruthy();
});
}
ดังนั้นในการทดสอบฉันสร้าง:
เยาะเย้ยบริการ
hubServiceMock
,ปลอม
messageChange = new Subject();
,ปลอม
gameChange = new Subject();
,ฉันใช้สำหรับทั้ง
.next
,และฉันตั้งค่าสปายสำหรับคุณสมบัติ:
spyOnProperty(hubServiceMock, 'messageChange', 'get').and.returnValue( messageChange );
spyOnProperty(hubServiceMock, 'gameChange', 'get').and.returnValue( gameChange );
ทำไมมันไม่ได้ผลกับฉัน? ฉันได้รับข้อผิดพลาด:
ไม่สามารถอ่านคุณสมบัติ 'สมัครสมาชิก' ของไม่ได้กำหนด
คำตอบ
มันไม่ทำงานเพราะhubServiceMock
ไม่ได้มีวิชาปลอมของตนmessageChange
และคุณจะต้องตั้งพวกเขาก่อนที่จะเรียกgameChange
new SignalRService(hubServiceMock)
const hubServiceMock = jasmine.createSpyObj('HubConnectionService', [
'isConnectionStarted',
]);
const messageChange = new Subject();
const gameChange = new Subject();
// add this
hubServiceMock.messageChange = messageChange;
hubServiceMock.gameChange = gameChange;
จากนั้นควรใช้งานได้อาจจำเป็นต้องมีการปรับเปลี่ยนเล็กน้อย
ฉันขอแนะนำให้ใช้ lib ล้อเลียนสำหรับกรณีดังกล่าวเพื่อหลีกเลี่ยงความเจ็บปวด
ตัวอย่างเช่นกับng-mocksการทดสอบอาจมีลักษณะดังนี้:
describe('SignalRService', () => {
beforeEach(() => MockBuilder(SignalRService, ITS_MODULE));
const hubServiceMock = {
messageChange: new Subject(),
gameChange: new Subject(),
};
beforeEach(() => MockInstance(HubConnectionService, hubServiceMock));
it('Service_ShouldBeCreated', () => {
const signalrService = MockRender(SignalRService).point.componentInstance;
expect(signalrService).toBeTruthy();
hubServiceMock.messageChange.next({});
hubServiceMock.gameChange.next({});
// next assertions.
});
}
ฉันลงเอยด้วยวิธีการที่ฉันฉีดบริการเยาะเย้ยเช่นนี้:
hubServiceMock = TestBed.inject(HubConnectionService);
จากนั้นฉันก็เยาะเย้ยของฉันSubject
เช่นนี้:
it('Service_ShouldBeCreated', () => {
spyOn(hubServiceMock.messageChange, 'next');
spyOn(hubServiceMock.gameChange, 'next');
expect(signalrService).toBeTruthy();
});
และในการทดสอบอื่น ๆ ฉันสามารถใช้วิธีการบริการที่เยาะเย้ยเช่นนั้นได้:
let spyIsConnectionStarted = spyOn(hubServiceMock, 'isConnectionStarted');
spyIsConnectionStarted.and.returnValue(true);