模拟HttpClient进行组件测试aurelia类

时间:2017-04-26 15:12:37

标签: testing integration-testing aurelia

我有一个看起来像这样的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请求,并且没有后端运行。如何以我控制响应的方式模拟HttpClient?

注意:#waitFor()是我从here派生的函数,我用它创建了一个要点here。我为#waitFor()版本创建了pull request。当它被接受时,要点变得无关紧要。

1 个答案:

答案 0 :(得分:0)

您需要切换到使用注入的服务。你的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注入一个mock,如下所示:

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()
    })
  })
})