title: Angular Unit Test: Moking Service inside a service or moking an abstract class
body: <p>I want to test a service that extends a abstract class. This abstract class implements the constructor and the method <code>getId</code>.</p>
  
  <p>Follows the code:</p>
  
  <pre><code>export abstract class ClientCacheService {
      private subscriptionId: string;
  
      protected getId(key :string, prefix:string=""): string {
          return `${this.subscriptionId}_${prefix}_${key}`;
      }
  
      constructor() {
          this.subscriptionId = new AppContextService().organizationKey();
      }
  
      abstract setCache(key :string, prefix:string, object: ICacheble): void;
      abstract getCache(key :string, prefix:string): ICacheble | null;
      abstract removeCache(key :string, prefix:string): void;
  }
  
  @Injectable()
  export class MemoryCacheService extends ClientCacheService {
      constructor() {
          super();
      }
      setCache(key: string, prefix: string, object: ICacheble): void {
          window[this.getId(key, prefix)] = JSON.stringify(object);
      }    
      getCache(key: string, prefix: string): ICacheble | null {
          let res = window[this.getId(key, prefix)];
          return res ? JSON.parse(res) : null;
      }
      removeCache(key: string, prefix: string): void {
          delete window[this.getId(key, prefix)];
      }
  }
  </code></pre>
  
  <p>I have two options:</p>
  
  <ol>
  <li>Mock the <code>ClientCacheService</code></li>
  <li>Mock the <code>AppContextService</code> that is incide of the constructure <code>ClientCacheService</code></li>
  </ol>
  
  <p>What I want is the second option (mock the <code>AppContextService</code>), but I could accept the first option as well as a good answer.</p>
  
  <p>As you can see in the following code, I give a try on mocking the <code>ClientCacheService</code>, but the MemoryCacheService does not has a <code>subscriptionId</code> defined, making my 'should be possible set cache' test case wrong.</p>
  
  <pre><code>import { MemoryCacheService } from "./memory-cache.service";
  import { ICacheble } from "interfaces/cacheble.interface";
  import { TestBed, inject } from "@angular/core/testing";
  import { ClientCacheService } from "./client-cache.service";
  
  export class CacheableObject implements ICacheble {
      prop1: String;
      prop2: Boolean;
      constructor() {
          this.prop1 = "prop1 testable";
          this.prop2 = true;
      }
      equals(cacheableObject: CacheableObject): boolean {
          return this.prop1 === cacheableObject.prop1 &amp;&amp;
                 this.prop2 === cacheableObject.prop2;
      }
  }
  
  export class MockClientCacheService {
      private subscriptionId: string;
      constructor() {
          this.subscriptionId = "Just a subscription";
      }
  }
  
  describe('MemoryCacheService Test cases', () =&gt; {
      let memoryCacheService: MemoryCacheService;
      beforeEach(()=&gt; {
          TestBed.configureTestingModule({
              providers: [
                  { provide: ClientCacheService, useClass: MockClientCacheService },
                  MemoryCacheService
              ]
          });
      });
  
      it('should be possible instantiate it', inject([MemoryCacheService], (memoryCacheService:MemoryCacheService)=&gt; {
          expect(memoryCacheService).toBeDefined();
      }));
  
      it('should be possible set cache',()=&gt; {
          let cacheableObject: CacheableObject = new CacheableObject();
          memoryCacheService.setCache("test_key", "test_prefix", cacheableObject);
          let storedObject: CacheableObject = memoryCacheService.getCache("test_key", "test_prefix") as CacheableObject;
          expect(storedObject.equals(cacheableObject)).toBeTruthy();
      });
  
  });
  </code></pre>