# Unit testing where(this).use(that)

**URL:** <https://forum.ionicframework.com/t/unit-testing-where-this-use-that/45254>\
**Category:** ionic-v3\
**Created:** [March 2, 2016, 7:56am UTC](https://forum.ionicframework.com/t/unit-testing-where-this-use-that/45254 "2016-03-02T07:56:10Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![xr0master](https://avatars.discourse-cdn.com/v4/letter/x/b4bc9f/32.png) [@xr0master](https://forum.ionicframework.com/u/xr0master)\
**Post date:** [March 2, 2016, 7:56am UTC](https://forum.ionicframework.com/t/unit-testing-where-this-use-that/45254/1 "2016-03-02T07:56:11Z")

</div>

Hi all,  
**TL;DR;** What is best practice do something like **where(this).use(that)** in Ionic 2/Angular 2?

For example, I used:  
**test.ts**

```auto
    import {BarcodeScanner} from 'ionic-native';

    extend class Test {
      public openScan(_BarcodeScanner?): Promise<any> {
        if (!_BarcodeScanner) {
          _BarcodeScanner = BarcodeScanner;
        }

        return _BarcodeScanner.scan().then((barcodeData) => {});
      }
    }

```

**test.spec.ts**

```auto
    class MockBarcodeScanner {
      public static scan(): Promise<any> {
        return new Promise((resolve, reject) => resolve({
          'cancelled': false,
          'format': 'QR_CODE',
          'text': 'any text'
        }));
      }
    }

    export function main(): void {
      'use strict';
      
      beforeAll(() => {
        test = new Test();
      });

      describe('Test', () => {
       it('Get something text', () => {
          test.openScan(MockBarcodeScanner).then((response) => {
            expect(response.text).toBe('something');
          });
        });
      })
    }

```

It works but I changed my original code for the test here

```
openScan(_BarcodeScanner?)

```

and pass the mock like argument from the test

**BUT** Maybe I can explain to the test something like: if it call BarcodeScanner, then it use MockBarcodeScanner? And I no need send the mock like argument?

Thanks you.

PS Sorry for my bad English.

---

<div class="post-metadata">

**Author:** ![swarner](https://avatars.discourse-cdn.com/v4/letter/s/5f9b8f/32.png) [@swarner](https://forum.ionicframework.com/u/swarner)\
**Post date:** [March 2, 2016, 1:58pm UTC](https://forum.ionicframework.com/t/unit-testing-where-this-use-that/45254/2 "2016-03-02T13:58:25Z")

</div>

If I understand correctly, you are trying to use a mocked BarcodeScanner or similar when testing. In order to test it in this example you changed your code to support passing in the BarcodeScanner and you are trying to find a way to do it where you do not have to pass the BarcodeScanner.

If this is correct, you should use Angular2’s Dependency Injection framework which is build in to Ionic 2. You would want to do something like this:

```
import {BarcodeScanner} from 'ionic-native';
import {Injectable} from 'angular2/core';

@Injectable()
extend class Test {

    private barcodeScanner: BarcodeScanner;

    constructor(barcodeScanner: BarcodeScanner) {
        this.barcodeScanner = barcodeScanner;
    }

    public openScan(): Promise<any> {
        return this.barcodeScanner.scan().then((barcodeData) => {});
    }
}

```

test.spec.ts

```
class MockBarcodeScanner {
    public static scan(): Promise<any> {
        return new Promise((resolve, reject) => resolve({
            'cancelled': false,
            'format': 'QR_CODE',
            'text': 'any text'
        }));
    }
}

export function main(): void {
          
    beforeEachProviders(() => [
        provide((BarcodeScanner), {useClass: MockBarcodeScanner}),
        Test
    ]);

    describe('Test', () => {
        it('Get something text', inject([Test], (test: Test)=> {
            test.openScan(MockBarcodeScanner).then((response) => {
                expect(response.text).toBe('something');
            });
        });
  })
}

```

The DI framework will create an instance of BarcodeScanner to be used by the Test class when the Test class is injected. The constructor of Test does not need to be called by you as it is handled by the DI framework. In the spec, adding the beforeEachProviders block will provide the two specified providers (BarcodeScanner and Test in this example), however the BarcodeScanner reference now will refer to MockBarcodeScanner. When Test is injected in this reference it will be given the MockBarcodeScanner rather than the standard.

See [Pascal Precht’s blog](http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html) for better understanding of DI in Angular2 (and by extension Ionic 2)

---

<div class="post-metadata">

**Author:** ![xr0master](https://avatars.discourse-cdn.com/v4/letter/x/b4bc9f/32.png) [@xr0master](https://forum.ionicframework.com/u/xr0master)\
**Post date:** [March 2, 2016, 6:58pm UTC](https://forum.ionicframework.com/t/unit-testing-where-this-use-that/45254/3 "2016-03-02T18:58:04Z")

</div>

You understand correctly. Thank you.

But if the Test class is @Page and not service?

---

<div class="post-metadata">

**Author:** ![swarner](https://avatars.discourse-cdn.com/v4/letter/s/5f9b8f/32.png) [@swarner](https://forum.ionicframework.com/u/swarner)\
**Post date:** [March 4, 2016, 1:36pm UTC](https://forum.ionicframework.com/t/unit-testing-where-this-use-that/45254/4 "2016-03-04T13:36:27Z")

</div>

I’m not really sure, as the @Page elements don’t appear to be intended for injection. I would probably still do the beforeEachProviders call providing the barcode scanner mock, but not Test, and inside of the it block I would inject a barcode scanner and create a new test using the constructor, passing it the barcode scanner.

Something like:

```
export function main(): void {
      
    beforeEachProviders(() => [
        provide((BarcodeScanner), {useClass: MockBarcodeScanner})
    ]);

    describe('Test', () => {
          // This will inject BarcodeScannerMock as we are providing that in place of
          // BarcodeScanner
        it('Get something text', inject([Test], (barcodeScanner: BarcodeScanner)=> {
            let test = new Test(barcodeScanner);
            test.openScan(MockBarcodeScanner).then((response) => {
                expect(response.text).toBe('something');
            });
        });
    })
```
