Mocking 和 Fakes

未匹配的标注

AdonisJS 为其大多数第一方软件包提供了虚假的实现。你可以使用 fakes 来获得更好的测试体验,而无需手动模拟部分代码库。

邮件

你可以通过调用 Mail.fake 方法来伪造外发电子邮件。一旦调用此方法,应用程序中与 Mail 对象交互的所有其他部分都不会发送真正的电子邮件。相反,它们将被收集在内存中以进行断言。

import { test } from '@japa/runner'
import Mail from '@ioc:Adonis/Addons/Mail'

test('register user', async ({ assert, client }) => {
  const mailer = Mail.fake()

  await client
    .post('register')
    .form({
      email: 'virk@adonisjs.com',
      password: 'secret'
    })

  // 断言
  assert.isTrue(mailer.exists((mail) => {
    return mail.subject === 'Welcome to AdonisJS'
  }))

  Mail.restore()
})

Mail.fake

调用 Mail.fake 只会为默认邮件程序创建一个假值。但是,你可以将邮件程序的名称显式传递给 fake。

// 伪造默认邮件
Mail.fake()

// 伪造的 smtp 和 s3 邮件
Mail.fake(['smtp', 's3'])

Mail.restore

完成测试后,您可以恢复选定或所有邮件的假值。

// 恢复默认邮件
Mail.restore()

// 恢复 smtp 和 s3 邮件
Mail.restore(['smtp', 's3'])

// 恢复所有伪造的邮件
Mail.restoreAll()

查找消息

你可以使用 existsfindfilter 方法检查发送的消息。所有方法都接受消息属性的子集或回调。

assert.isTrue(mailer.exists({ subject: 'Welcome to AdonisJS' }))

assert.isTrue(mailer.exists((mail) => {
  return mail.subject === 'Welcome to AdonisJS'
}))

const message = mailer.find((mail) => {
  return mail.to[0].address === 'virk@adonisjs.com'
})

console.log(message)

事件

你可以通过调用 Event.fake 方法来伪造事件。该方法接受一个可选的事件数组来伪造。否则,所有即将发生的事件都是伪造的。

import Event from '@ioc:Adonis/Core/Event'

// 伪造所有事件
Event.fake()

// 伪造特定事件
Event.fake(['new:user', 'update:email'])

Event.restore

你可以使用 Event.restore 方法恢复事件。

Event.restore()

查找事件

Event.fake 方法返回一个假发射器,你可以使用它来稍后获取或查找事件。

const emitter = Event.fake()

assert.isTrue(emitter.exists('new:user'))
assert.isTrue(emitter.exists((event) => {
  return event.name === 'new:user' && event.data.id === 1
}))

你可以使用 findfilter 方法来查找特定事件。

const emitter = Event.fake()

emitter.find('new:user')
// 返回 { name: 'new:user', data: any }

emitter.filter((event) => event.name.startsWith('invite:'))
// 返回 { name: 'new:user', data: any }

Drive

你可以通过调用 Drive.fake 方法来伪造 Drive 实现。默认情况下,仅伪造默认磁盘。但是,你也可以显式定义磁盘名称。

import Drive from '@ioc:Adonis/Core/Drive'

// 伪造默认磁盘
Drive.fake()

// 伪造本地和 S3 存储
Drive.fake(['s3', 'local'])

Drive.restore

你可以通过调用 Drive.restore 方法来恢复伪造的磁盘,也可以传递磁盘名称来还原,否则将还原默认磁盘。或者,使用 Drive.restoreAll 方法恢复所有磁盘。

// 恢复默认磁盘
Drive.restore()

// 恢复特定磁盘
Drive.restore(['s3', 'local'])

// 恢复所有磁盘
Drive.restoreAll()

查找文件

Drive.fake 方法返回可用于稍后获取或查找文件的假驱动器对象。

const drive = Drive.fake()

// 查找文件是否存在
assert.isTrue(await drive.exists('avatar.jpg'))

// 断言文件大小
assert.isBelow(await drive.bytes('avatar.jpg'), 1000 * 1000 * 20)

// 断言文件内容
assert.equal(await drive.get('package.json'), JSON.stringify({}))

哈希

你可以通过调用 Hash.fake 方法来伪造 Hash 模块。伪造期间不执行密码哈希,hash.make 方法返回相同的值。

import Hash from '@ioc:Adonis/Core/Hash'

// 假哈希实现
Hash.fake()

const hashed = await Hash.make('secret') // 返回 "secret"
await Hash.verify(hashed, 'secret') // 返回 "true"

// 恢复假
Hash.restore()

模拟对象

AdonisJS 不附带任何开箱即用的模拟库。你可以自由使用 Node 生态系统中的任何模拟库。

下面是一个小例子,展示了使用 SinonJS 来模拟 ES6 类。

export default class ExchangeService {
  constructor (private baseCurrency: string) {}

  public getRate(currency: string, amount: number) {
  }
}

在测试期间,你可以导入 ExchangeService 并模拟 getRate 方法,如下所示。

import { test } from '@japa/runner'

import sinon from 'sinon'
import ExchangeService from 'App/Services/ExchangeService'

test('transfer payment', async ({ client }) => {
  const mock = sinon.mock(ExchangeService.prototype)
  mock
    .expects('getRate')
    .once()
    .withArgs('INR', 600)
    .returns(6)

  await client
    .post('/transfer')
    .form({ currency: 'INR', amount: 600 })

  mock.verify()
  mock.restore()
})

模拟网络请求

你可以使用 nock 模拟传出的网络请求。由于 nock 通过覆盖 Node.js http.request 来工作,它几乎适用于所有 HTTP 客户端,包括 axiosgot

下面是一个模拟 Stripe 的 charges API 的例子。

// 文件名: test_helpers/mocks.ts
import nock from 'nock'

export function mockStripeCharge() {
  return nock('https://api.stripe.com/v1')
    .post('/charges')
    .reply(201, (_, requestBody) => {
      return {
        id: 'ch_3KjEE62eZvKYlo2C0n3A7N3E',
        object: 'charge',
        amount: requestBody.amount,
      }
    })
}

现在,你可以使用 mockStripeCharge 辅助工具,如下所示。

import { mockStripeCharge } from 'TestHelpers/mocks'

test('complete purchase with stripe charge', async () => {
  mockStripeCharge()
  // 在此处调用条带 API
})

本文章首发在 LearnKu.com 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://learnku.com/docs/adonisjs/5.x/te...

译文地址:https://learnku.com/docs/adonisjs/5.x/te...

上一篇 下一篇
贡献者:1
讨论数量: 0
发起讨论 只看当前版本


暂无话题~