Last active
October 8, 2018 13:47
-
-
Save ianjamieson/85e64524737df6d6eb85ce39945ff894 to your computer and use it in GitHub Desktop.
Observables Testing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe('Observables Example', () => { | |
// set up observable | |
let observable: Observable<any>; | |
// mock the return value from the form | |
const formValue: string = 'United Kingdom'; | |
it('should match observable', () => { | |
// create a mock observable, which triggers once and returns the formValue. This is effectively | |
// like triggering a form change | |
observable = of(formValue, 'testing'); | |
// you can check that the observable is of Observable type | |
// see here for marble syntax, https://github.com/ReactiveX/rxjs/blob/master/doc/marble-testing.md | |
// this example uses of, where all the values are triggered at the same time | |
// the a matches the a property in the object, the b matches the b and the pipe shows observable complete | |
expect(observable).toBeObservable(cold('(ab|)', {a: formValue, b: 'testing'})); | |
}); | |
it('should match observable', () => { | |
// I could mock a hot observable, like below: | |
// see more on hot vs. cold observables https://medium.com/@benlesh/hot-vs-cold-observables-f8094ed53339 | |
// "-" represents a hypothetical period of time | |
observable = hot('--a-b', {a: formValue, b: 'testing'}); | |
// and now we can test that this works | |
expect(observable).toBeObservable(cold('--a-b', {a: formValue, b: 'testing' })); | |
}); | |
it('should match observable with a map', () => { | |
// so, if I want to pipe my hot observable, with a map | |
// now each time a and b events are triggered, we map our values... | |
observable = hot('--a-b|', {a: formValue, b: 'testing'}).pipe( | |
// map each value, append "mapped" | |
map(originalValue => originalValue + 'mapped') | |
); | |
// I can test for this, I'd expect the values to have mapped at the end! | |
expect(observable).toBeObservable(cold('--a-b|', { a: formValue + 'mapped', b: 'testingmapped'})); | |
}); | |
it('should test actual code', () => { | |
/** | |
* If there was an example like: | |
this.filteredCountries$ = this.subscriptionGroup.controls.clientCountry.valueChanges | |
.pipe( | |
startWith(''), | |
map(value => AccountDetailsComponent.autocompleteFilter(this.countries, value)) | |
); | |
* We could mock the valueChanges observable, so you could spyOn | |
spyOn(instance.subscriptionGroup.controls.clientCountry, 'valueChanges').and.returnValue(hot('--a--')) | |
* Alternatively you could trigger a form change | |
fixture.nativeElement.querySelector('#formField').dispatchEvent(new Event('change')); | |
*/ | |
// I will use the mocking example, we can consider what I am doing on the next line | |
// as mocking the form change obseravble, over an arbritraty length of time, trigger | |
// two form change events, (a and b) and on each of those, return the values | |
const formChangeObservable$: Observable<any> = hot('-a-b', {a: 'UK', b: 'Germany'}); | |
// set up some sort of filter | |
function filter(v: string): string { | |
return v + 'filtered'; | |
} | |
// pipe as per code example | |
const filteredCountries$: Observable<any> = formChangeObservable$.pipe( | |
// startWith operator forces a value to the beginning | |
startWith(''), | |
// in this map, we only return one value type | |
map(value => filter(value)) | |
); | |
// i have added "s" as we have used the startWith operator | |
// the letters used are arbitrary, but they should have a matching object key | |
// otherwise it wil return the key as the value (eg. s) | |
expect(filteredCountries$).toBeObservable(cold('sa-b', {s: filter(''), a: filter('UK'), b: filter('Germany')})); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment