如何通过监视可观察的angularfire2进行单元测试?

时间:2018-12-11 15:12:11

标签: angular angularfire2

尝试将angluarfire2存根以用于我的服务。现在我得到的错误是:<toHaveBeenCalledWith> : Expected a spy, but got Function.

如何进行设置,以便能够拨打正确的电话?我想让事情尽可能地可重用。

import { TestBed } from '@angular/core/testing';
import { AngularFirestore } from '@angular/fire/firestore';

import { of } from "rxjs";
import { FirebaseService } from './firebase.service';
describe('FirebaseService', () => {

let service: FirebaseService;

let collectionSpy = jasmine.createSpy("collection").and.callFake((path: string) => {
    return of([{
    title: "Example Post",
    body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla commodo dui quis.",
    }]);
});

let afStub: any = {
    collection:()=>{
    return {
        valueChanges:collectionSpy
    }
    }
};

beforeEach(() => {
    TestBed.configureTestingModule({
    providers:[
        { provide: AngularFirestore, useValue: afStub }
    ],      
    })
    service = TestBed.get(FirebaseService); 
});

it('should have a list method', () => {
    afStub.collection('fakeCollection').valueChanges(); //calling directly to see if it works (which it doesn't)
    expect(afStub.collection).toHaveBeenCalledWith('fakeCollection')
});

});

1 个答案:

答案 0 :(得分:2)

  

更新了此答案,以显示valueChanges()方法中返回的Observable

出现错误是因为您将collection专门设置为函数,而不是带有声明的间谍:

let afStub: any = {
    collection:()=>{
    return {
        valueChanges:collectionSpy
    }
    }
};

您可以简单地将collection声明为间谍(例如,使用jasmine.createSpy()),但是我认为您的问题比这个简单的解决方案要深得多,因此,我整理了一个Stackblitz来展示我将如何测试这样的东西。既然我现在只是提供了简化版本,就可以随意进行分叉并使用自己的服务实现进行编辑。

对于间谍(在服务中模拟/替换AngularFirestore),我使用了一个嵌套的spyObject,因为我个人发现该语法更简单,更简洁,但是您可以使用createSpy并手动建立一个间谍对象也很容易模拟AngularFirestore。这是我的声明方式:

const ReturnResult = {
    title: "Example Post",
    body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla commodo dui quis."
};
const collectionSpy = jasmine.createSpyObj({
    valueChanges: of(ReturnResult)
})
const afSpy = jasmine.createSpyObj('AngularFirestore', {
    collection: collectionSpy
});

然后在我创建的要测试的模拟服务中,我制定了list ()方法,因为这似乎是您要测试的方法,然后将您在下面的注释中提到的订阅放入其中。像这样:

list() {
    this.firebaseService.collection('fakeCollection').valueChanges().subscribe(x=>console.log(x));
}

然后我将规范更新为以下内容:

it('should have a list method', () => {
    service.list();
    expect(collectionSpy.valueChanges).toHaveBeenCalled();
    expect(afSpy.collection).toHaveBeenCalledWith('fakeCollection');
});

查看Stackblitz中的所有详细信息。如果单击测试窗口最底部的“控制台”,则会看到返回信息已打印在控制台日志中,显示结果已传递到Observable上的.subscribe()方法。

我希望这会有所帮助。