如何在函数内部进行SpyOn函数并返回假值

时间:2019-07-16 04:54:53

标签: angular typescript unit-testing karma-jasmine spyon

这个问题似乎是相同的,但绝对不是重复的。

在我的功能之一中,我正在呼叫this.cordovaFile.readAsArrayBuffer(this.cordovaFile.dataDirectory, key)

cordovafile.readAsArrayBuffer()从ipad文件存储中读取数据,但是在单元测试中我无法做到这一点,因为它在浏览器中运行,因此我正在使用SpyOn来获取假值,我很难做到这一点。

下面的功能可以帮助我吗?

    private getTimesheetByKey(key: TIMESHEET_KEYS): Observable<TimesheetModel> {
        let timesheet: TimesheetModel;

        return from(
            this.cordovaFile
                .readAsArrayBuffer(this.cordovaFile.dataDirectory, key)
                .then(compressedConfirmation => {
                    const start = moment();
                    const uint8Array = new Uint8Array(compressedConfirmation);
                    const jsonTimeSheet = this.LZString.decompressFromUint8Array(uint8Array);

                    timesheet = new TimesheetModelFromJson(<JsonTimesheetModel>(
                        JSON.parse(jsonTimeSheet)
                    ));
                    this.saveTimesheetByKey(key, timesheet);
                    return timesheet;
                })
                .catch((error: Error) => {})
        );
    }

这就是我要编写的单元测试的方式,我不知道如何准确地进行SpyOn this.cordovaFile.readAsArrayBuffer(this.cordovaFile.dataDirectory, key)并返回值

it('should save the Timesheet to file storage', () => {
        spyOn(LocalStorageTimesheetService, 'getTimesheetByKey')
            .and.callThrough(cordovaFile.readAsArrayBuffer())
            .and.returnValue(timesheet);

        expect(timesheet).toEqual();
    });

this.cordovaFile.readAsArrayBuffer()应该返回假值如下所示

timesheet = {
            startOfWork: '2019-07-02T02:00:00.000Z',
            notifications: [],
            additionalExpenses: [],
            manualTimesheetEntries: [],
            endOfWork: undefined,
            isSubmitted: false,
            attendanceType: 'FREE',
        };

1 个答案:

答案 0 :(得分:1)

我不认为spyOn(LocalStorageTimesheetService, 'getTimesheetByKey')会起作用,因为getTimesheetByKey是私有函数。首先使其public

此外,通过spying readAsArrayBuffer,您将可以控制结果 compressedConfirmation 而不是timesheettimesheet是在new Uint8Array()

上执行compressedConfirmation etc etc 个操作后计算得出的

如果您担心仅在调用getTimesheetByKey时检查该值是否已保存,则可以这样写:

it('should call "saveTimesheetByKey()" when getTimesheetByKey() is called', () => {
    const compressedConfirmationMock = 'some_val'; // expected Mock value of compressedConfirmation
    spyOn(LocalStorageTimesheetService.cordovaFile, 'readAsArrayBuffer').and.returnValue(Promise.resolve(compressedConfirmationMock));
    spyOn( LocalStorageTimesheetService, 'saveTimesheetByKey').and.callThrough();
    LocalStorageTimesheetService.getTimesheetByKey(SOME_VAL_OF_TYPE_TIMESHEET_KEYS);
    expect(LocalStorageTimesheetService.saveTimesheetByKey).toHaveBeenCalled();
});


it('should save the Timesheet to file storage using saveTimesheetByKey()', () => {
    // here unit test the logic of saveTimesheetByKey() function 
    // which is actually saving the data. 
})


it('should perform some logic where getTimesheetByKey() is called', () => {
   // improve the "it" statement. 
   spyOn(LocalStorageTimesheetService, 'getTimesheetByKey')
        .and.returnValue(of({
            startOfWork: '2019-07-02T02:00:00.000Z',
            notifications: [],
            additionalExpenses: [],
            manualTimesheetEntries: [],
            endOfWork: undefined,
            isSubmitted: false,
            attendanceType: 'FREE',
        }));
   // and here write unit test that function which is using value of `timesheet` returned by calling "getTimesheetByKey()"
   //  expect block here
})

请注意,我将单元测试逻辑分为3个不同的块的方式。单元测试应该是更孤立的测试,并且应该写在功能逻辑的细粒度上。