如何通过监视 angularfire2 observable 进行单元测试?
How to unit test by spying on angularfire2 observable?
正在尝试关闭 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')
});
});
Updated this answer to show Observable returned in valueChanges()
method
您收到错误是因为您专门将 collection
设置为函数而不是带有声明的间谍:
let afStub: any = {
collection:()=>{
return {
valueChanges:collectionSpy
}
}
};
您可以简单地将集合声明为间谍(例如 jasmine.createSpy()
),但我认为您的问题比这个简单的解决方案更深入一些,因此我整理了一个 Stackblitz展示我可能如何处理这样的测试。随意分叉它并使用您自己的服务实现进行编辑,因为我现在只是放入一个简化版本。
对于间谍(服务中的 mock/replace 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 中的所有详细信息。如果单击测试 window 最底部的 "Console",您将看到 return 打印在控制台日志上,表明结果已传递给 .subscribe()
Observable 上的方法。
希望对您有所帮助。
正在尝试关闭 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')
});
});
Updated this answer to show Observable returned in
valueChanges()
method
您收到错误是因为您专门将 collection
设置为函数而不是带有声明的间谍:
let afStub: any = {
collection:()=>{
return {
valueChanges:collectionSpy
}
}
};
您可以简单地将集合声明为间谍(例如 jasmine.createSpy()
),但我认为您的问题比这个简单的解决方案更深入一些,因此我整理了一个 Stackblitz展示我可能如何处理这样的测试。随意分叉它并使用您自己的服务实现进行编辑,因为我现在只是放入一个简化版本。
对于间谍(服务中的 mock/replace 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 中的所有详细信息。如果单击测试 window 最底部的 "Console",您将看到 return 打印在控制台日志上,表明结果已传递给 .subscribe()
Observable 上的方法。
希望对您有所帮助。