简体   繁体   English

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

[英]How to unit test by spying on angularfire2 observable?

Trying to stub out angluarfire2 to use in my services. 尝试将angluarfire2存根以用于我的服务。 Right now the error I get is: <toHaveBeenCalledWith> : Expected a spy, but got Function. 现在我得到的错误是: <toHaveBeenCalledWith> : Expected a spy, but got Function.

How do I set things up so that I'm able to make the proper call? 如何进行设置,以便能够拨打正确的电话? I'd like to make things as reusable as possible. 我想让事情尽可能地可重用。

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')
});

});

Updated this answer to show Observable returned in valueChanges() method 更新了此答案以显示valueChanges()方法中返回的Observable

You are getting the error because you specifically set up collection as a function rather than a spy with the declaration: 之所以会出现错误,是因为您专门通过声明将collection设置为函数而不是间谍:

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

You could simply declare collection as a spy (with jasmine.createSpy() for example), but I think your problems go a little deeper than just this simple solution, so therefore I put together a Stackblitz to show how I might approach testing something like this. 您可以简单地将collection声明为间谍(例如,使用jasmine.createSpy() ),但是我认为您的问题比这个简单的解决方案要深得多,因此,我整理了一个Stackblitz来展示如何进行类似的测试这个。 Feel free to fork this and edit with your own service implementation since I just put in a simplified version for now. 因为我现在只是提供了简化版本,所以可以随意分叉并使用自己的服务实现进行编辑。

For the spy (to mock/replace AngularFirestore in the service) I used a nested spyObject since I personally find that syntax simpler and more concise, but you could use createSpy and manually build up an object of spies to mock AngularFirestore pretty easily as well. 对于间谍(在服务中模拟/替换AngularFirestore ),我使用了一个嵌套的spyObject,因为我个人发现该语法更简单,更简洁,但是您可以使用createSpy并手动构建一个间谍对象来模拟AngularFirestore非常容易。 Here is how I declared it: 这是我的声明方式:

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
});

Then in the mock service I created to test, I made the list () method, since that appears to be what you are trying to test, and put the subscribe you mentioned in the comments below into it. 然后,在我创建的要测试的模拟服务中,我创建了list ()方法,因为这似乎是您要测试的内容,并将您在下面的注释中提到的订阅放入其中。 Like this: 像这样:

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

Then I updated the spec to the following: 然后,我将规格更新为以下内容:

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

Check out all the details in the Stackblitz. 在Stackblitz中查看所有详细信息。 If you click on the "Console" on the very bottom of the test window, you will see that the return is printed on the console log, showing the result was passed through to the .subscribe() method on the Observable. 如果单击测试窗口最底部的“控制台”,您将看到返回信息已打印在控制台日志中,显示结果已传递到Observable的.subscribe()方法。

I hope this helps. 我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM