Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Types have separate declarations of a private property mock service unit test Angular 7

I am trying to create a mockService but I am getting an error " Types have separate declarations of a private property" , to me it seems the declaration is equal and not different but it says is not in the error. I am doing this test in a component that has the service injected!!! Yes, I want to test it here with the mock test.

My code for the mock service:

class MockDataservice {   
result: any;
constructor(private http: HttpClient){
    sendCodeToServer() {
     return this.result;
     } 
}

describe('HomePage', () => 
...
{
 ...  
beforeEach(() => { 
...
    service = new MockDataservice(http);  
    component = new HomePage(platform, service, splash, statusbar, barcode, alert, http, loading, router);

The original service:

export class DataStorageService {
    result: any;
      constructor(private http: HttpClient) {
      }

sendToServer(data) {
const headers = new HttpHeaders().set('Content-Type', 'application/json');
   return new Promise((resolve, reject) => {
   this.http.post(endpoindURL, data, { headers: headers })
        .toPromise().then((data) => {
          resolve(data);
        }).catch((err) => {
          console.log(err);
          reject(err);
        });
    });
  }
}

Service usage in the component:

export class HomePage {
barcodeScannerOptions: BarcodeScannerOptions;
    constructor(private platform: Platform, private **dataStorageService**: 
    DataStorageService,
    private splashScreen: SplashScreen,
    private statusBar: StatusBar, private barcodeScanner: BarcodeScanner, public 
    alertController: AlertController,
    private http: HttpClient, private loadingController: LoadingController, 
    private router: Router) {

    this.initializeApp();

    this.barcodeScannerOptions = {
          showTorchButton: true,
          showFlipCameraButton: true
        };
      }

    function doesSomething(){
    this.dataStorageService.sendToServer(data).then((res) => {
    }

I get the error here in the home.spec file, in the word service

component = new HomePage(platform, service, splash, statusbar, barcode, alert, http, loading, router);

and the error is

MockDataservice is not assignable to parameter of type //DataStorageService. Types have separate declarations of a private property http.ts

like image 881
AnaCS Avatar asked Apr 24 '19 14:04

AnaCS


1 Answers

So here's the exhaustive answer what's happening. I constructed a minimal example that reproduces the behavior: Broken example on TypeScript Playground. You can actually see the exact same error message.

What's going here? The Component expects an instance of the actual Service class in its constructor. MockService is not a Service. It just coincidentally has the same constructor parameters and the same method names. The compiler does not know that the two are actually compatible (i.e. implement the same interface), and therefore throws an error.

How do we fix this? Work with actual object oriented abstraction. As Service and MockService are actually interchangeable, we need to let the compiler know that. How do we do that? By having them implement the same interface.

We'll just define a Service interface. We'll have a ConcreteService, which contains the default behavior, and which implements Service. We'll also have our MockService, which will implement the same Service, but have mocked behavior: Working example on TypeScript playground.,

like image 171
fjc Avatar answered Oct 13 '22 01:10

fjc