mercredi 8 mars 2017

Why use a BehaviorSubject as a spy in Angular2 tests instead of a plain Subject

I am in reference to the following blog post: http://ift.tt/2mixH0o

In one of the tests (see below) a BehaviorSubject is used to act as a spy.

I understand the requirement for a Subject (Observable + Observer) but why use a BehaviorSubject instead of a plain Subject?

Can anyone please explain?

describe('ComposeCmp', () => {
  let actions: BehaviorSubject<any>;
  let time: CurrentTime;

  beforeEach(() => {
    // this subject acts as a "spy"
    actions = new BehaviorSubject(null);

    // dummy implementation of CurrentTime
    time = () => '2016-08-19 9:10AM';
  });

  it('emits a reply action on submit', () => {
    // a fake activated route
    const route = {
      snapshot: {
        root: {
          firstChild: { params: { id: 11 } }
        }
      }
    };
    const c = new ComposeCmp(<any>route, time, actions);

    // performing an action
    c.form.setValue({
      title: 'Categorical Imperative vs Utilitarianism',
      body: 'What is more practical in day-to-day life?'
    });
    c.onSubmit();

    // reading the emitted value from the subject
    // to make sure it matches our expectations
    expect(actions.value.conversationId).toEqual(11);
    expect(actions.value.payload).toEqual({
      title: 'Categorical Imperative vs Utilitarianism',
      body: 'What is more practical in day-to-day life?',
      createdAt: '2016-08-19 9:10AM'
    });
  });
});

edit: I have a further interrogation: at what precise point is the actions BehaviorSubject subscribed to and by which subscribers? The component under test is given below:

@Component({moduleId: module.id, templateUrl: 'compose.html'})
class ComposeCmp {
  form = new FormGroup({
    title: new FormControl('', Validators.required),
    body: new FormControl('')
  });

  constructor(private route: ActivatedRoute,
              private currentTime: CurrentTime,
              private actions: Actions) {}

  onSubmit() {
    const routerStateRoot = this.route.snapshot.root;
    const conversationRoute = routerStateRoot.firstChild;
    const conversationId = +conversationRoute.params['id'];

    const payload = Object.assign({},
      this.form.value,
      {createdAt: this.currentTime()});

    this.actions.next({
      type: 'reply',
      conversationId: conversationId,
      payload: payload
    });
  }
}

Aucun commentaire:

Enregistrer un commentaire