Skip to main content
 首页 » 编程设计

angular中使用导入的第三方依赖项对 Angular 服务方法进行单元测试

2026年04月21日65www_RR

我有一个 Angular 服务,它导入第三方依赖项。我调用依赖项来为我提供浏览器指纹,然后将其存储在服务中。

我不确定如何在测试中模拟此依赖项,以便我可以断言它已被调用并模拟返回值。

这是服务:

import { Inject, Injectable } from '@angular/core'; 
import * as Fingerprint2 from 'fingerprintjs2'; 
 
@Injectable() 
export class ClientInfoService { 
    public fingerprint: string | null = null; 
 
    constructor() { 
    } 
 
    createFingerprint(): any { 
        return new Fingerprint2(); 
    } 
 
    setFingerprint(): void { 
        let fprint = this.createFingerprint(); 
        setTimeout(() => fprint.get(hash => this.fingerprint = hash), 500); 
    } 
 
    getFingerprint(): string | null { 
        return this.fingerprint; 
    } 
 
} 

这是当前的测试代码:

import { TestBed } from '@angular/core/testing'; 
import { ClientInfoService } from './client-info.service'; 
 
describe('Client Info Service', () => { 
    const hash = 'a6e5b498951af7c3033d0c7580ec5fc6'; 
    let service: ClientInfoService; 
 
    beforeEach(() => { 
        TestBed.configureTestingModule({ 
            providers: [ClientInfoService], 
        }); 
        service = TestBed.get(ClientInfoService); 
    }); 
 
    test('should be defined', () => { 
        expect(service).toBeDefined(); 
    }); 
 
 
    describe('get the fingerprint', () => { 
 
        test('it should be null', () => { 
            let fprint = service.getFingerprint(); 
            expect(fprint).toBeNull(); 
        }); 
 
        test('it should be the hash value', () => { 
            service.fingerprint = hash; 
            let fprint = service.getFingerprint(); 
            expect(fprint).toEqual(hash); 
        }); 
 
    test('it should get the hash value after setting', () => { 
        jest.useFakeTimers(); 
        service.createFingerprint = jest.fn().mockReturnValue(() => { 
            return { 
                get: function (cb) { 
                    return cb(hash); 
                } 
            }; 
        }); 
        spyOn(service, 'createFingerprint'); 
        service.setFingerprint(); 
        jest.runAllTimers(); 
        expect(service.createFingerprint).toHaveBeenCalled(); 
        expect(service.fingerprint).toEqual(hash); 
    }); 
 
    }); 
 
}); 

请您参考如下方法:

我不会将第三方直接导入到服务中,因为很难对它们进行单元测试(特别是如果他们做了一些棘手的事情,例如 http 调用或 DOM 操作等......)

创建像第三方工厂一样工作的 Angular 服务可能是个好主意:

import * as Fingerprint2 from 'fingerprintjs2'; 
 
@Injectable() 
export class FingerprintFactory { 
    create(): any { 
        return new Fingerprint2(); 
    } 
} 

之后,您可以在 ClientInfoService 中注入(inject) FingerprintFactory 并使用其 create 方法创建 Fingerprint2 实例。

此外,在 ClientInfoService 中模拟 FingerprintFactory 也非常容易