title: Test optional constructor parameter in Angular (7+)
body: <p>I have a problem and would appreciate a helping hand.</p>
  
  <p>We have a service with a constructor using optional params like so</p>
  
  <pre><code>@Injectable()
  export class OurService {
      constructor(
          private someService: SomeService,
          @Optional() someOption: SomeOption,
      ) {
          if(someOption) {
              this.someService.doSomethingWith(someOption);
          }
          // ...do other things
      }
      // ...other methods
  }
  </code></pre>
  
  <p>Now I want to test that and get good coverage which means there need to be tests where OurService gets instantiated one time with, the other time without someOption and also I want to expect that someService.doSoemthingWith has been called.</p>
  
  <p>I usually setup my testing-module like so</p>
  
  <pre><code>let service: OurService;
  let someService: SomeService;
  
  beforeEach(async(() =&gt; {
      TestBed.configureTestingModule({
          imports: [],
          declarations: [],
          providers: [
              { provide: SomeService, useClass: MockSomeService },
          ],
      }).compileComponents();
  }));
  
  beforeEach(() =&gt; {
      service = TestBed.get(AuthService);
      someService = TestBed.get(SomeService);
  });
  </code></pre>
  
  <p>Now I have strong difficulty trying to get all my tests right. How do I test these 3 things?</p>
  
  <ul>
  <li>should call someService when someOption was provided</li>
  <li>should not call someService when someOption was not provided</li>
  <li>should test the other things regardless</li>
  </ul>
  
  <p>Here my attempts (among heaps of others..):</p>
  
  <ol>
  <li><p>install a spy and see if method has been called</p>
  
  <pre><code>it('blabla', () =&gt; {
  
      spyOn(someService, 'doSomethingWith');
      // I guess the spy is too late because TestBed get already called the constructor
  
      expect(someService.doSomethingWith).toHaveBeenCalled();
  });
  </code></pre></li>
  <li><p>attempt to add a provider for this one test</p>
  
  <pre><code>it('blabla', () =&gt; {
  
      spyOn(someService, 'doSomethingWith');
  
      TestBed.overrideProvider(SomeOption, { useValue: MockSomeOption }); // MockSomeOption is defined somewhere
      TestBed.compileComponents();
      service = TestBed.get(SomeService);
  
      // does not work
      expect(someService.doSomethingWith).toHaveBeenCalled();
  });
  </code></pre></li>
  <li><p>inject smeOption (dont know how, hence this code is wic)</p>
  
  <pre><code>it('blabla', inject([SomeService], (someService: SomeService) =&gt; {
  
      //const injector = Injector.create({ providers: [{ provide: SomeOption, useValue: MockSomeOption }] });
  
      spyOn(someService, 'doSomethingWith');
  
      // ?? what now ??
      expect(someService.doSomethingWith).toHaveBeenCalled();
  });
  </code></pre></li>
  <li><p>Add someOption to the TestBed setup like so</p>
  
  <pre><code>beforeEach(async(() =&gt; {
  
    TestBed.configureTestingModule({
      imports: [],
      declarations: [],
      providers: [
          { provide: SomeService, useClass: MockSomeService },
          { provide: SomeOption, useClass: MockSomeOption },
      ],
    }).compileComponents();
  }));
  
  // problem now is that it is always provided. and I can not test the else-path
  </code></pre></li>
  </ol>
  
  <p>How can I set up my service once as required by most tests, and then add the someOption in one test and call the constructor again so that my spy can do its secret espionage job?</p>