模拟组件测试Aurelia类的HTTPCLIENT



我有一个看起来像这样的aurelia类:

import {HttpClient} from 'aurelia-fetch-client'
export class Lobby {
  constructor() {
    this.propertyName = 'description'
  }
  fetch() {
    new HttpClient().fetch('/api/package.json')
      .then(response => response.json())
      .then(data => {
        this.response = data[this.propertyName] || Object.keys(data)
      })
  }
}

我想为此类添加一个组件测试,其中我触发#fetch()并控制测试中的服务器响应,从本质上模拟了HTTP后端。我的测试看起来像这样:

describe('the lobby', () => {
  let component
  beforeEach(done => {
    component = StageComponent.withResources('lobby')
      .inView('<lobby></lobby>')
      .boundTo({})
    component.bootstrap(aurelia => {
      aurelia.use.standardConfiguration()
    })
    component.create(bootstrap).then(() => {
      window.Promise = Promise
      done()
    })
  })
  it('should fetch a result via HttpClient', (done) => {
    const inputElement = document.querySelector('input');
    const button = document.querySelector('button')
    const output = () => document.querySelector('pre')
    expect(inputElement.value).toBe('description')
    button.click()
    waitFor(() => output().innerText !== '').then(() => {
      expect(output().innerText).toBe('foo');
      done()
    })
  })
})

这是不起作用的,因为Aurelia-fetch-Client执行实际的HTTP请求,并且没有后端运行。我如何以控制响应的方式模拟HTTPCLEINT?

注意:#waitFor()是我从这里派生的功能,我在这里创建了一个要点。我为我的#waitFor()版本创建了一个拉请请求。当它被接受时,要点变得无关紧要。

您需要切换到使用注射服务。您的Aurelia类看起来像这样:

import {HttpClient} from 'aurelia-fetch-client'
import {inject} from 'aurelia-framework'
@inject(HttpClient)
export class Lobby {
  constructor(httpClient) {
    this.HttpClient = httpClient
    this.propertyName = 'description'
  }
  fetch() {
    this.HttpClient.fetch('/api/package.json')
      .then(response => response.json())
      .then(data => {
        this.response = data[this.propertyName] || Object.keys(data)
      })
  }
}

注意@inject(HttpClient),而不是简单地使用导入的HTTPCLIENT。这样,您可以从这样的测试中为HTTPCLIENT注入模拟:

import { StageComponent } from 'aurelia-testing'
import { bootstrap } from 'aurelia-bootstrapper'
import { HttpClient } from 'aurelia-fetch-client'
describe('the lobby', () => {
  let component
  beforeEach(done => {
    component = StageComponent.withResources('lobby')
      .inView('<lobby></lobby>')
      .boundTo({})
    component.bootstrap(aurelia => {
      aurelia.use.standardConfiguration()
      aurelia.container.autoRegister(HttpClient, class {
        fetch(url) {
          return new Promise((resolve, reject) => {
            resolve({
              json: () => { return { "description": "foo" } }
            })
          })
        }
      })
    })
    component.create(bootstrap).then(() => {
      window.Promise = Promise
      done()
    })
  })
})

最新更新