Angular 2 Unit Testing a service that uses a Observable and Redux Rxjs selector
<p>I am trying to setup a Karma Jasmine Unit test for a Angular 2 service. The service is called <strong>CreditService</strong>. The service has a observable property <strong>_credit$</strong> and implements a ng2-redux selector <strong>@select(s => s.credit)</strong> to get the credit object from a Redux store.</p>

<pre><code>import {Injectable, Inject} from '@angular/core';
import {ICreditData, ICreditSubmissionData, ContractType, ICredit} from '../../store/type-store/credit.types';
import 'rxjs/add/operator/map';
import {AppStateService} from '../app-state-service/app-state-service';
import {select} from 'ng2-redux';
import {Observable} from 'rxjs';
import {PromiseService} from '../promise/promise-service';


export interface ICreditResponse {
  errors?: string[];
  token?: string;
  response?: ICreditData;
  submission?: ICreditSubmissionData;
}

export interface ICreditLead {
  address: string;
  aptSuite: string;
  city: string;
  state: string;
  zipCode: number;
  email: string;
  monthlyIncome: number;
  birthDate: string;
  socialSec: number;
  contactPolicy: boolean;
}

@Injectable()
export class CreditService {

  @select(s =&gt; s.credit)
  private _credit$: Observable&lt;ICredit&gt;;
  public isPostGA2: boolean = false;

  constructor(@Inject(AppStateService) private _appStateService: AppStateService,
              @Inject(PromiseService) private _promiseService: PromiseService) {
    this.setupSubscriptionForPostGA2();
  }
  /**
   * Method will setup subscription to determine of credit has been
   * pulled or credit has already been pulled and exists in the Redux store.
   */
  public setupSubscriptionForPostGA2(): void {
    // subscribe to the store check for isPostGA2
    this._credit$.subscribe(
      credit =&gt; {
        let creditDataExists = (credit.data !== undefined) || credit.data !== null;
        let creditLeadIDExists = (credit.data.LeadID !== undefined) || credit.data.LeadID !== null;
        let creditHistoryExists = (creditDataExists &amp;&amp; creditLeadIDExists);
        this.isPostGA2 = (credit.loadComplete || creditHistoryExists);
      },
      err =&gt; {}
    );
  }


}
</code></pre>

<p>The unit test is pretty basic at this point. I check to see if  the CreditService is defined. My unit test looks as follows: </p>

<pre><code>import { fakeAsync, inject, TestBed } from '@angular/core/testing';
import { DtmAppModule } from '../../modules/app.module';
import { configureTests } from '../../tests.configure';
import { CreditService } from './credit-service';
import {MockAppStateService} from '../../mock/service/app-state-service-mock';
import {MockPromiseService} from '../../mock/service/promise-service-mock';
import { AppStateService } from '../../services/app-state-service/app-state-service';
import { PromiseService } from '../../services/promise/promise-service';
import {NgRedux} from 'ng2-redux';


describe('Service: Credit', () =&gt; {
  let creditService: CreditService = null;

  beforeEach(done =&gt; {
    const configure = (testBed: TestBed) =&gt; {
      testBed.configureTestingModule({
        imports: [DtmAppModule],
        providers: [
          { provide: AppStateService, useClass: MockAppStateService },
          { provide: PromiseService, useClass: MockPromiseService },
          { provide: NgRedux, useClass: NgRedux },
        ]
      });
    };

    configureTests(configure).then(testBed =&gt; {
      done();
    });
  });

  // Inject the service
  beforeEach(inject([CreditService], (service: CreditService) =&gt; {
    creditService = service;
  }));

  //Do a simple test
  it('should have a defined service', () =&gt; {
    expect(creditService).toBeDefined(false);
  });
});
</code></pre>

<p>I am getting a exception when executing the test (see below). I believe the exception is because I am trying to preform a 'select' method on a undefined Redux store object.</p>

<ul>
<li>How do I fix the basic '<strong>toBeDefined</strong>' test? </li>
<li>How can I inject Rxjs mock store for testing purposes?</li>
<li>Is there a way to mock the return from the <strong>_credit$ Observable</strong> ?</li>
</ul>

<p>I am getting a exception when executing the test (see below). I believe the exception is the 'select' of a undefined Redux store.</p>

<pre><code>TypeError: Cannot read property 'select' of undefined
        at CreditService.getter [as _credit$] (webpack:///~/ng2-redux/lib/decorators/select.js:23:0 &lt;- src/tests.entry.ts:150235:47)
        at CreditService.setupSubscriptionForPostGA2 (webpack:///src/services/credit/credit-service.ts:47:17 &lt;- src/tests.entry.ts:24169:17)
        at new CreditService (webpack:///src/services/credit/credit-service.ts:40:2 &lt;- src/tests.entry.ts:24155:14)
        at DynamicTestModuleInjector.get (DynamicTestModule.ngfactory.js:367:71)
        at DynamicTestModuleInjector.getInternal (DynamicTestModule.ngfactory.js:638:53)
        at DynamicTestModuleInjector.NgModuleInjector.get (webpack:///~/@angular/core/src/linker/ng_module_factory.js:94:0 &lt;- src/tests.entry.ts:91283:27)
        at TestBed.get (webpack:///~/@angular/core/bundles/core-testing.umd.js:1114:0 &lt;- src/tests.entry.ts:9003:51)
        at webpack:///~/@angular/core/bundles/core-testing.umd.js:1120:50 &lt;- src/tests.entry.ts:9009:65
        at Array.map (native)
        at TestBed.execute (webpack:///~/@angular/core/bundles/core-testing.umd.js:1120:0 &lt;- src/tests.entry.ts:9009:33)
</code></pre>