getTestScheduler().flush()刷新测试中的所有 observables。有没有办法精细地刷新 observables?
例如 cold('--x', {x: {}}).flush()
我正在尝试使用 RxJs Observables 在 Angular 中做一个非常简单的测试,但我做的很短。这就是我基本上要测试的内容:
// We're inside some Angular component here...
let testMe = 0;
function somethingOrOther(): void {
this.someService.methodReturningObservable()
.subscribe(
(nextValue: number): void => {
testMe += nextValue;
}
)
}
Run Code Online (Sandbox Code Playgroud)
testMe当后面的 observablemethodReturningObservable发出值时,如何测试是否正确更新?
我用这个尝试过:
it(`works 'cuz I want it to`, fakeAsync(() => {
spyOn(this.someService, 'methodReturningObservable').and.returnValue(cold('a', {a: 10}));
tick();
expect(component.testMe).toBe(10);
}));
Run Code Online (Sandbox Code Playgroud)
所以,tick()这里似乎没有做任何事情。没有什么能让我cold对我的间谍发出任何价值。
我尝试了getTestScheduler.flush(),如弹珠部分下的https://netbasal.com/testing-observables-in-angular-a2dbbfaf5329所示。
我可以使用这样的弹珠在 observable 上发出值吗?这在 AngularJS 中非常容易,只需触发一个摘要,但我似乎无法让 Anguar 让我进入下一个可观察的回调。
触发效果后,我想在单元测试中测试两个可观察值,以获取此部分代码的100%代码覆盖率。因为a window.location.href被触发,所以我无法正确测试。
export class RouteHelper {
static redirectToExternalUrl(url: string): any {
window.location.href = url;
}
}
Run Code Online (Sandbox Code Playgroud)
影响
@Effect()
handleCreatePaymentSuccess$: Observable<
{} | routerActions.Go
> = this.actions$.pipe(
ofType(cartConfigActions.CREATE_PAYMENT_SUCCESS),
switchMap((action: any) => {
if (action.payload.redirect) {
/* istanbul ignore next */
return Observable.create(
RouteHelper.redirectToExternalUrl(action.payload.redirect),
);
} else {
return of(
new routerActions.Go({
path: [RouteHelper.paths['validate']],
}),
);
}
}),
);
Run Code Online (Sandbox Code Playgroud)
测试else条件
it('should dispatch router action Go on success if no redirect url is provided', () => {
const payload = { redirect: …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个基本的 ngrx 效果测试。但是我不断收到错误,因为 TypeError: expect(...).toBeObservable is not a function。
这是一个使用 Angular 7 的新项目设置。我以前在 angular 4 中运行的项目没有问题。
最初认为这可能与软件包有关,因此将所有软件包升级到最新,但还没有运气。
我试图测试一个非常简单的 observable,如 expect(effects.test$).toBeObservable(5); 但它给出了同样的错误。正如标题中提到的,我使用的是 jasmine-marbles,版本是 0.4.1。
我写了一个过滤输入可观察的管道。在管道中,如果源未及时发出预期值,我使用 timeout() 运算符指定超时以中止等待。我想用 jasmine-marbles 测试超时情况,但我无法让它工作。我相信那expect(source).toBeObservable()源发出之前先计算。
待测管道:
source = cold('a', { a: { id: 'a' } }).pipe(
timeout(500),
filter((a) => false),
catchError((err) => {
return of({ timeout: true })
}),
take(1)
);
Run Code Online (Sandbox Code Playgroud)
使用 toPromise() 进行测试按预期工作:
expect(await source.toPromise()).toEqual({ timeout: true });
Run Code Online (Sandbox Code Playgroud)
用茉莉花大理石测试
const expected = cold('500ms (a|)', { a: { timeout: true } });
expect(source).toBeObservable(expected);
Run Code Online (Sandbox Code Playgroud)
因错误而失败
Expected $.length = 0 to equal 2.
Expected $[0] = undefined to equal Object({ frame: 500, notification: Notification({ kind: 'N', …Run Code Online (Sandbox Code Playgroud) 在我的 angular 项目中,我有一个服务,用于状态管理以在组件之间共享一些数据,如下所示:
@Injectable({ providedIn: "root"})
export class NameStateService {
private _filteredNames$: Subject<Name[]> = new Subject();
private _filteredNamesObs$: Observable<Name[]>;
constructor() {
this._filteredNamesObs$ = this._filteredNames$.asObservable();
}
public updateFilteredNames(val: Name[]): void {
this._filteredNames$.next(val);
}
public get filteredNames$(): Observable<BillingAccount[]> {
return this._filteredNamesObs$;
}
}
Run Code Online (Sandbox Code Playgroud)
状态管理基于主题和可观察,这是 rxjs 世界中的典型用法。
而对于这个服务的单元测试,我想使用rxjs/testing模块支持的弹珠测试功能。解决方法如下:
describe("Name state service ", () => {
let nameStateService: NameStateService;
let scheduler: TestScheduler;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
NameStateService
]
});
nameStateService = TestBed.get(NameStateService);
scheduler = new TestScheduler((actual, expected) => expect(actual).toEqual(expected));
}); …Run Code Online (Sandbox Code Playgroud) 我有一个人们可以在这里下载的快速演示:https://stackblitz.com/edit/angular-vczzqp只需点击右上角的导出,在您最喜欢的终端中运行install并ng test使用您喜欢的浏览器.
对我来说,基本上问题似乎是Jasmine的内部时间与对象不匹配.
下面是测试以及我得到的确切错误.请参阅app/Test下的示例以获取完整的测试类
it('should return a GET_GENERIC_FAILED when the services throws', () => {
const action = new genericActions.GetAllGenericAction();
genericsService.getAllGenerics.and.returnValue(Observable.throw({}));
actions$.stream = hot('a', { a: action });
const expected = cold('b', { b: new genericActions.GetGenericFailedAction() });
expect(effects.getAllGenerics).toBeObservable(expected);
});
Run Code Online (Sandbox Code Playgroud)
而错误
Expected
[Object({
frame: 0,
notification: Notification({
kind: 'N',
value: GetGenericFailedAction({
type: '[GENERIC] Get Generic Failed'
}),
error: undefined,
hasValue: true
})
}), Object({
frame: 0,
notification: Notification({
kind: 'C',
value: undefined,
error: …Run Code Online (Sandbox Code Playgroud) 我目前想用ngrx/effects测试我的效果.我跟着降价,但是当我想要运行我的测试时我有一个错误.
Cannot find module 'rxjs/testing' from 'jasmine-marbles.umd.js'
Run Code Online (Sandbox Code Playgroud)
这是我的代码(目前我没有做到期望,我只想要我的测试运行):
import { TestBed } from '@angular/core/testing'
import { provideMockActions } from '@ngrx/effects/testing'
import { ReplaySubject } from 'rxjs/ReplaySubject'
import { hot, cold } from 'jasmine-marbles'
import { Observable } from 'rxjs/Observable'
import { VersionService } from '../../service/version/version.service'
import { DataEffects } from './data.effect'
import { RequestVersions, ReceiveVersions } from './data.action'
describe('My Effects', () => {
let versionService: VersionService
let effects: DataEffects
let actions: Observable<any>
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
// any …Run Code Online (Sandbox Code Playgroud) 尝试对现有的和最近迁移的Angular 7项目运行简单的效果测试。但是我得到如下错误。
错误:未 在新TestHotObservable(node_modules / jasmine-marbles / es6 / src / test-observables.js:21:39)的getTestScheduler(node_modules / jasmine-marbles / es6 / src / scheduler.js:11:1)初始化任何测试计划程序)在Module.hot(node_modules / jasmine-marbles / es6 / index.js:7:1)
我的效果规范文件中的代码是茉莉花大理石的基本标准检查。
const action = new Load(request);
const completion = new LoadSuccess(result);
actions$ = hot('-a-', { a: action});
const response = cold('-a|', {a: result});
const expected = cold('--b', {b: completion});
service.getSomething.and.returnValue(result);
expect(effects.load$).toBeObservable(expected);
Run Code Online (Sandbox Code Playgroud)
有人看过并解决过此错误吗?
我有一个项目,我广泛使用角度 HttpClient 请求作为流的基础。我很想使用茉莉花弹珠来测试这些请求,因为它似乎是流单元测试的“行业标准”。
然而,我正在努力让整个事情正常工作,要么 HttpTestingController 失败,要么大理石失败。我建立了一个堆栈闪电战来证明我的观点。
我正在使用 Angular 8 编写一个应用程序。
我决定使用带有BehaviorSubject 的 rxjs 存储来进行简单的状态管理。
基本上,我的代码是一个存储、加载和更新用户权限的服务。有时,此信息将在 HTTP 调用后来自服务器,有时此信息将来自本地存储。用户权限更改后,所有订阅者都会得到更新。
这是我的 StackBlitz:https://stackblitz.com/edit/rxjs-state-management-get-set 请单击“添加配置文件”按钮以查看其运行情况。
这是我设置了单元测试的 StackBlitz:https://stackblitz.com/edit/rxjs-state-management-get-set-xpptmr
我已经使用基本的订阅者和完成技术编写了一些单元测试,但我想更深入地挖掘。
我读到我们可以使用“marbles”来测试 Observable 随着时间的推移的价值:https://rxjs-dev.firebaseapp.com/guide/testing/internal-marble-tests
我想使用弹珠来测试代码中的“加载”功能。
服务存储的代码片段:
@Injectable({
providedIn: 'root'
})
export class PersonaService {
private readonly data: BehaviorSubject<IPersonaData>;
public readonly sharedData: Observable<IPersonaData>;
constructor() {
this.data = new BehaviorSubject<IPersonaData>(null);
this.sharedData = this.data.asObservable() as Observable<IPersonaData>;
}
public load(): void {
const storedPersonaData: IPersonaData = {
currentPersonaIndex: null,
personas: []
};
const storedCurrentIndex: string = localStorage.getItem(Constants.KEYS.defaultPersonaIndex) as string;
if (storedCurrentIndex != null) {
storedPersonaData.currentPersonaIndex …Run Code Online (Sandbox Code Playgroud) 我想测试一下,如果一个 observable 从它的一个操作符内部捕获到一个抛出的错误,我会得到预期的结果 observable。
下面的服务返回一个 observable,根据其错误参数是否抛出错误。
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/merge';
import 'rxjs/add/operator/do';
import 'rxjs/add/observable/of';
export function service(obs1: Observable<number>, obs2: Observable<number>, error: boolean = false) {
return obs1.merge(obs2)
.map((elt) => elt * 2)
.do(() => {
if (error) {
throw new Error();
}
})
.catch(() => Observable.of(0));
}
Run Code Online (Sandbox Code Playgroud)
有了这个茉莉花测试
import { cold } from 'jasmine-marbles';
import { Observable } from 'rxjs/Observable';
import { service } from './catch';
describe('Test Marbles', () => {
it('should …Run Code Online (Sandbox Code Playgroud) jasmine-marbles我正在尝试使用但出现错误进行简单的测试
这是我的测试代码:
describe('MarbleTestingComponent', () => {
it('should test marble syntax', () => {
const provided = search('e');
const expected = cold('(e|)', {e: 'e'});
console.log(expected, provided);
expect(provided).toBeObservable(expected);
})
});
Run Code Online (Sandbox Code Playgroud)
这是我收到的错误:
Error:
Expected: (e|),
Received: (?|),
Expected:
[{"frame":0,"notification":{"kind":"N","value":"e","hasValue":true}},{"frame":0,"notification":{"kind":"C","hasValue":false}}]
Received:
[{"frame":0,"notification":{"kind":"N","value":"e"}},{"frame":0,"notification":{"kind":"C"}}],
Run Code Online (Sandbox Code Playgroud)
如果我使用该jest框架,上面的代码可以工作,但我想让它与 Angular 设置附带的默认测试框架一起工作
感谢您对解决此错误的任何帮助,谢谢
jasmine-marbles ×13
angular ×8
rxjs ×8
ngrx-effects ×4
unit-testing ×4
angular7 ×2
jasmine ×2
rxjs-marbles ×2
jest ×1
marble ×1
ngrx ×1
rxjs6 ×1
testing ×1
timeout ×1