简体   繁体   中英

Problem with testing async functions in Angular with Jasmine

I am unit testing my Ionic 4 app with Jasmine. At the moment I am getting errors when running almost all my tests because I am doing something wrong with the async/await functions. The error that I get is: "Error: Timeout - Async function did not complete within 5000ms." I have changed this timeout_interval to another larger number and I still get this error.

My code is:

beforeEach(async(() => {
  const storage = new Storage({         
    // Define Storage
    name: '__mydb',
    driverOrder: ['indexeddb', 'sqlite', 'websql']
  });  
    
  component = new HomepagePage(storage);

  TestBed.configureTestingModule({
    declarations: [ HomepagePage ],
    imports: [
      IonicModule.forRoot(), 
      RouterTestingModule,
      IonicStorageModule.forRoot()
    ]
  }).compileComponents();

  fixture = TestBed.createComponent(HomepagePage);
  component = fixture.componentInstance;
  fixture.detectChanges();
}));

it('should create', async () => {
  let home = jasmine.createSpyObj('home_spy',['getprice'])
  const result = await home.getprice
  expect(component).toBeTruthy();
});

describe('before logged in', () => {
  let home = jasmine.createSpyObj('home_spy',['getprice'])
    
  it('shows the price', async () => {
    const result = await home.getprice
    expect(home.getprice.length).toEqual(2);
  });
});

My app is working fine when I am using it. However, could it be that the error is in the code itself? An example of the getprice() function is:

async getprice() {
    var price_eth :number
    var price_btc :number

    try {
        var url_btc = "https://api.binance.com/api/v1/klines?symbol=BTCUSDT&interval=1m";
        var url_eth = "https://api.binance.com/api/v1/klines?symbol=ETHUSDT&interval=1m"
        const btc = await axios.get(url_btc)
        const eth = await axios.get(url_eth)

        if (btc.data.length != 0 && eth.data.length != 0) {
           this.loaded = 'yes'
        } else { 
            this.loaded='no'
        }
        this.time = new Date(btc.data[btc.data.length-1][0]).toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
        price_btc = Math.floor(btc.data[btc.data.length-1][1])
        price_eth = Math.floor(eth.data[eth.data.length-1][1])

       //These global variables are declared so they display the price but they are not used for any other functions.
       this.glob_price_btc = price_btc
       this.glob_price_eth = price_eth

       return {
        'price_btc':price_btc,'price_eth':price_eth
       }

    } catch {
        this.loaded = 'no';
        return
    }
}

I think you misunderstood the function beforeEach() . beforeEach() should be used to setup the test environment and will be called before an unittest will be exeuted. Here is an example how it would be more correct and to setup the timeout duration.

describe("xyz test suite", () => {
    //called before every unittest
    beforeEach(function() {
        //Do setup stuff
    });
    
    it('shows the price', async () => {
        const result = await getSomething()
        expect(result).toEqual(2);
    });

}, 10000 <- Timeout in milliseconds)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM