title: Jasmine createSpyObj service not registering calls
body: <p>After reading what feels like every single post about Jasmine spies not registering calls, here's my code with that exact problem:</p>
  
  <pre><code>describe( 'shared.FormAutocompleteComponent', () =&gt; {
      let component: FormAutocompleteComponent;
      let fixture: ComponentFixture&lt;FormAutocompleteComponent&gt;;
      let displayCtrl: FormControl;
  
      const mockService = jasmine.createSpyObj( 'dynSearchService', ['search', 'lookup'] );
      mockService.lookup.and.returnValue( of( { unlocode: 'ZRH/CH', name: 'Zürich' } ) );
      mockService.search.and.returnValue( of( [{ unlocode: 'ZRH/CH', name: 'Zürich' }] ) );
  
      beforeEach( async(() =&gt; {
          TestBed.configureTestingModule( {
              declarations: [FormAutocompleteComponent],
              providers: [{ provide: DynamicSearchService, useValue: mockService }],
              imports: [
                  NoopAnimationsModule, ReactiveFormsModule,
                  RouterTestingModule.withRoutes( [] ),
                  MatInputModule, MatAutocompleteModule, MatIconModule
              ]
          } )
              .compileComponents();
      } ) );
  
      beforeEach(() =&gt; {
          displayCtrl = new FormControl();
          const group = new FormGroup( {} );
          group.addControl( 'foobar', displayCtrl );
  
          fixture = TestBed.createComponent( FormAutocompleteComponent );
          component = fixture.componentInstance;
          component.config = {
              name: 'foobar',
              formControl: 'text',
              label: 'My foobar',
              lookupApi: 'location',
              searchApi: 'locations'
          };
          component.group = group;
          fixture.detectChanges();
      } );
  
      it( 'should create', () =&gt; {
          expect( component ).toBeTruthy();
      } );
  
      fit( 'should correctly extend single term to wildcard', async(() =&gt; {
          // arrange
          displayCtrl.setValue( 'zrh' );
          fixture.detectChanges();
          // act
          component.search();
          // assert
          expect( mockService.search ).toHaveBeenCalled();
          expect( mockService.search ).toHaveBeenCalledWith( 'zrh*', 'locations' );
      } ) );
  } );
  </code></pre>
  
  <p>The DynamicSearchService is injected into the FormAutocompleteComponent, and placing a console.log directly before the component calls DynamicSearchService#search shows that the method is clearly being called. Another console.log shows that the results returned match those for the train Jasmine spy.</p>
  
  <pre><code>3396 (Windows 10 0.0.0)]: Connected on socket rlx5hC9uWlNSUz0pAAAA with id 73910165
  LOG: 'callDynSearchService with displayCtrl.value=zrh'
  LOG: 'callDynSearchService with displayCtrl.value=zrh'
  LOG: 'About to run &lt;search&gt; on service with term zr* '
  LOG: 'About to run &lt;search&gt; on service with term zr* '
  LOG: 'Got results: [{"unlocode":"ZRH/CH","name":"Zürich"}]'
  LOG: 'Got results: [{"unlocode":"ZRH/CH","name":"Zürich"}]'
  Chrome 67.0.3396 (Windows 10 0.0.0) shared.FormAutocompleteComponent should correctly extend single term to wildcard FAILED
          Expected spy dynSearchService.search to have been called.
              at &lt;Jasmine&gt;
  </code></pre>
  
  <p>Running a test with</p>
  
  <pre><code>const srv = fixture.debugElement.injector.get( DynamicSearchService );
  expect( mockService ).toEqual( srv );
  </code></pre>
  
  <p>succeeds, the only cause left seems to be that the .search() call is never recorded on the spy. What am I doing wrong?</p>
  
  <p><strong>EDIT, 06/23/2018</strong></p>
  
  <p>Changing to defining a non-spy mockService (still injected 'useValue'), and then</p>
  
  <pre><code>fit( 'should correctly extend single term to wildcard', async(() =&gt; {
      // arrange
      let injectedService = TestBed.get( DynamicSearchService );
      spyOn( injectedService, 'search' ).and.callThrough();
      spyOn( injectedService, 'lookup' ).and.callThrough();
      displayCtrl.setValue( 'zrh' );
      fixture.detectChanges();
      // act
      component.search();
      // assert
      expect( injectedService.search ).toHaveBeenCalled();
  } ) );
  </code></pre>
  
  <p>debugging now shows that the service in the component is the same object as 'injectedService'. The proxy changes done by spyOn also show on the components service. However, Jasmine still records 'search' to never have been called.</p>