Переопределение поставщиков на основе тестирования в Angular - PullRequest
1 голос
/ 31 марта 2020

Я бы хотел переопределить поставщика услуг при тестировании Ngrx Effects для каждого теста, чтобы охватить ответы об успехах и неудачах.

То, что я до сих пор пробовал, - это предоставление моих услуг в TestBed как например:

describe('Account Effects', () => {

  let actions: ReplaySubject<any>;
  let effects: AccountEffects;
  let store: Store<IAccountsState>;

  const email = 'someone@gmail.com';
  const password = 'abc123!';

  beforeEach(async () => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
      ],
      providers: [
        AccountEffects,
        provideMockActions(() => actions),
        provideMockStore<IAccountsState>({ initialState }),
        {
          provide: AccountsService,
          useValue: { _signIn: () => of(null) }
        }
      ]
    });

   store = TestBed.get(Store);
  });


  beforeEach(async () => {
    effects = TestBed.get(AccountEffects);
  });
});

Затем в каждом тесте переопределите провайдера:

describe('signIn$ success', () => {
  beforeEach(() => {
    TestBed.overrideProvider(AccountsService, {
      useValue: {
        _signIn: () => of({ authenticated: true })
      }
    });
  });

  it('should dispatch signInSuccess when a successful response is received', () => {
    actions = new ReplaySubject(1);
    actions.next(AccountActions.signIn({ email, password }));

    effects.signIn$.subscribe(result => {
      expect(result).toEqual(AccountActions.signInSuccess({ email }));
    });
  });
});

Проблема, с которой я столкнулся, заключается в том, что accountService._signIn не является функцией:

Произошла ошибка в afterAll TypeError:

this.accountsService._signIn не является функцией

Мне нужно иметь возможность переопределить возвращаемое значение в каждом тестовом случае.

Я следил:

https://indepth.dev/testing-and-faking-angular-dependencies/

Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 31 марта 2020

Я думаю, вы должны изменить насмешку над AccountsService. Служба учетных записей - это класс, а вы издеваетесь над функцией. Вы должны изменить spe c, как показано ниже

class  AccountsServiceMock {
    _signIn(){
       of(null)
    }
}

TestBed.configureTestingModule({
  imports: [
    RouterTestingModule,
  ],
  providers: [
    AccountEffects,
    provideMockActions(() => actions),
    provideMockStore<IAccountsState>({ initialState }),
    {
      provide: AccountsService,
      useClass: AccountsServiceMock 
    }
  ]
});

Если вы хотите изменить возвращаемое значение входа в каждую spe c, вы можете посмотреть на него и установить возвращаемое значение. сделай работу.

0 голосов
/ 31 марта 2020

Так что я не могу быть полностью уверен, но я предполагаю, что у вас возникли проблемы из-за того, когда вы получите свой экземпляр эффектов (хотя я не очень знаком с Ngrx). Поскольку вы используете io c, экземпляр эффектов создается перед тем, как назначить значение для действий и перед изменением определения AccountsService, поэтому ваш тестовый вид выглядит следующим образом:

it('should dispatch signInSuccess when a successful response is received', () => {
  let accountsService: AccountsService = {
    _signIn: () => of({ authenticated: true })
  };
  let actions;
  let effects = new AccountEffects(actions, accountsService);
  accountsService = {
    _signIn: () => of({ authenticated: true })
  };

  actions = new ReplaySubject(1);
  actions.next(AccountActions.signIn({ email, password }));

  effects.signIn$.subscribe(result => {
    expect(result).toEqual(AccountActions.signInSuccess({ email }));
  });
});

Теперь Я не совсем уверен, почему он не видит эту первую _signIn функцию. Я бы попытался записать значение accountsService для консоли в вашем классе эффектов, чтобы увидеть, что происходит, но в любом случае вы столкнетесь с некоторыми проблемами, основанными на порядке, в котором вы определяете свои значения.

Итак, чтобы исправить ваш тест, я бы начал с назначения эффектов внутри теста, чтобы посмотреть, работает ли он. Затем вы можете настроить вещи так, как вам нужно, чтобы убедиться, что вы можете переопределить значения, когда захотите.

Так что-то вроде этого:

  it('should dispatch signInSuccess when a successful response is received', () => {
    actions = new ReplaySubject(1);
    actions.next(AccountActions.signIn({ email, password }));
    effects = TestBed.get(AccountEffects);

    effects.signIn$.subscribe(result => {
      expect(result).toEqual(AccountActions.signInSuccess({ email }));
    });
  });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...