如何模拟出一个Observable?我试图用三种不同的方式来模拟它

时间:2019-03-09 02:47:38

标签: angular unit-testing karma-jasmine rxjs6

我编写了许多单元测试来测试可观察性,但是由于某些原因,该测试无法像我编写的其他测试那样工作,但是我看不出问题是什么。

我想要ChangePasswordFacade.successful $的模拟返回一个返回true的Observable。即使我以前使用了下面的模拟策略,也无法正常工作。我尝试将ChangePasswordFacade注入测试。我尝试在TestBed提供程序的useValue中使用模拟成功$函数。我尝试了以下方法。它们都将成功$当作假。我怎样才能以不同的方式嘲笑它以返回true?

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PasswordChangeModalComponent } from './password-change-modal.component';
import { ReactiveFormsModule } from '@angular/forms';
import { PasswordChangeFormComponent } from '../../..';
import { DefaultPopoverComponent } from '@bis-angular/shared-components/pattern-library';
import { Store, StoreModule } from '@ngrx/store';
import {
  ChangePasswordFacade,
  UserInformationFacade,
  changePasswordInitialState,
  CHANGEPASSWORD_FEATURE_KEY,
  changePasswordReducer
} from '@bis-angular/users';
import { configureTestSuite } from 'ng-bullet';
import { of } from 'rxjs';

describe('PasswordChangeModalComponent', () => {
  let component: PasswordChangeModalComponent;
  let fixture: ComponentFixture<PasswordChangeModalComponent>;

  const childDefaultPopoverComponent = jasmine.createSpyObj('DefaultPopoverComponent', ['hideModal', 'showModal']);
  const childPasswordChangeFormComponent = jasmine.createSpyObj('PasswordChangeFormComponent', ['setFormControlsToEmpty']);

  const changePasswordFacadeSpy = jasmine.createSpyObj('ChangePasswordFacade', ['resetState']);

  configureTestSuite(() => {
    TestBed.configureTestingModule({
      imports: [
        ReactiveFormsModule,
        StoreModule.forRoot({}),
        StoreModule.forFeature(CHANGEPASSWORD_FEATURE_KEY, changePasswordReducer, {
          initialState: changePasswordInitialState
        })
      ],
      declarations: [PasswordChangeFormComponent, DefaultPopoverComponent, PasswordChangeModalComponent],
      providers: [Store, UserInformationFacade, ChangePasswordFacade]
    });
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(PasswordChangeModalComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    component.defaultPopoverComponent = childDefaultPopoverComponent;

    component.watchSuccessful = { unsubscribe: () => {} };
    spyOn(component.watchSuccessful, 'unsubscribe');
    const service = TestBed.get(ChangePasswordFacade);
    spyOn(service, 'successful$').and.returnValue(of(true));
  });


  describe('showPasswordChangeModal function ', () => {
    it('should call showModal and then not hide if not successful  ', () => {
      spyOn(component, 'hidePasswordChangeModal');
      component.successful$.subscribe((successful: boolean) => {
        expect(component.hidePasswordChangeModal).toHaveBeenCalled();
        expect(changePasswordFacadeSpy.resetState).toHaveBeenCalled();
        expect(component.watchSuccessful.unsubscribe).toHaveBeenCalled();
      });
      component.showPasswordChangeModal();
      expect(childDefaultPopoverComponent.showModal).toHaveBeenCalled();
    });
  });


});
import { Injectable } from '@angular/core';
import { select, Store } from '@ngrx/store';
import { ChangePasswordPartialState } from './change-password.reducer';
import { changePasswordQuery } from './change-password.selectors';
import { ChangePassword, ChangePasswordResetState } from './change-password.actions';
import { NewPassword } from '@bis-angular/users';

@Injectable()
export class ChangePasswordFacade {
  successful$ = this.store.pipe(select(changePasswordQuery.getSuccessful));

  initiated$ = this.store.pipe(select(changePasswordQuery.getInitiated));

  constructor(private store: Store<ChangePasswordPartialState>) {}

  changePassword(newPassword: NewPassword, userId: string) {
    this.store.dispatch(new ChangePassword(newPassword, userId));
  }

  resetState() {
    this.store.dispatch(new ChangePasswordResetState());
  }
}

2 个答案:

答案 0 :(得分:0)

这是我做的事情:我使用商店来调度一个将成功$更改为true的动作。现在是集成测试,而不是单元测试。

df2 = pd.DataFrame({'#timestamp':[-5,-4,-3,-2,-1,0],
                    'grid_U1':   [413.714,413.797,413.926,414.037,414.066,414.064],
                    'grid_U2':   [415.796,415.909,416.117,416.093,416.163,416.183],
                    'grid_U3':   [416.757,416.853,417.09,417.158,417.175,417.085]})

df1 = pd.DataFrame(index=range(0,10), columns=['col2_0','col3_0','col4_0'])

答案 1 :(得分:-1)

自此,您要访问successful$的类级别定义的ChangePasswordFacade

类似:

export class ChangePasswordFacade{
   successful$:observable // ... something like this
}

您应该尝试useValue

 configureTestSuite(() => {
    TestBed.configureTestingModule({
      imports: [
        ReactiveFormsModule,
        StoreModule.forRoot({}),
        StoreModule.forFeature(CHANGEPASSWORD_FEATURE_KEY, changePasswordReducer, {
          initialState: changePasswordInitialState
        })
      ],
      declarations: [PasswordChangeFormComponent, DefaultPopoverComponent, PasswordChangeModalComponent],
      providers: [Store, UserInformationFacade, 
                   {provide: ChangePasswordFacade , useValue: 
                     {
                         successful$ : of(true)
                     }
                   }'
                 ]
    });
  });