Mocking e Fakes
O AdonisJS vem com implementações falsas para a maioria de seus pacotes primários. Você pode usar fakes para ter uma melhor experiência de teste sem simular manualmente partes da sua base de código.
Mail
Você pode falsificar os e-mails de saída chamando o método Mail.fake
. Depois de chamar esse método, todas as outras partes do seu aplicativo que interagem com o objeto Mail
não enviarão e-mails reais. Em vez disso, eles serão coletados na memória para asserções.
import { test } from '@japa/runner'
// highlight-start
import Mail from '@ioc:Adonis/Addons/Mail'
// highlight-end
test('register user', async ({ assert, client }) => {
// highlight-start
const mailer = Mail.fake()
// highlight-end
await client
.post('register')
.form({
email: 'virk@adonisjs.com',
password: 'secret'
})
// highlight-start
// Time for assertions
assert.isTrue(mailer.exists((mail) => {
return mail.subject === 'Welcome to AdonisJS'
}))
Mail.restore()
// highlight-end
})
Mail.fake
Chamar Mail.fake
cria um fake apenas para o mailer padrão. No entanto, você pode passar explicitamente o(s) nome(s) dos mailers para o fake.
// Fake the default mailer
Mail.fake()
// Fake smtp and s3 mailers
Mail.fake(['smtp', 's3'])
Mail.restore
Depois de terminar o teste, você pode restaurar os fakes para mailers selecionados ou todos.
// Restore the default mailer
Mail.restore()
// Restore smtp and s3 mailers
Mail.restore(['smtp', 's3'])
// Restore all faked mailers
Mail.restoreAll()
Encontrando mensagens
Você pode verificar as mensagens enviadas usando os métodos exists
, find
ou filter
. Todos os métodos aceitam um subconjunto de propriedades de mensagem ou um retorno de chamada.
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)
Eventos
Você pode falsificar eventos chamando o método Event.fake
. O método aceita uma matriz opcional de eventos para falsificar. Caso contrário, todos os próximos eventos serão falsificados.
import Event from '@ioc:Adonis/Core/Event'
// Fake all events
Event.fake()
// Fake specific events
Event.fake(['new:user', 'update:email'])
Event.restore
Você pode restaurar eventos usando o método Event.restore
.
Event.restore()
Encontrando eventos
O método Event.fake
retorna um emissor falso que você pode usar para buscar ou encontrar eventos posteriormente.
const emitter = Event.fake()
assert.isTrue(emitter.exists('new:user'))
assert.isTrue(emitter.exists((event) => {
return event.name === 'new:user' && event.data.id === 1
}))
Você pode usar os métodos find
e filter
para encontrar eventos específicos.
const emitter = Event.fake()
emitter.find('new:user')
// returns { name: 'new:user', data: any }
emitter.filter((event) => event.name.startsWith('invite:'))
// returns { name: 'new:user', data: any }
Drive
Você pode falsificar a implementação do Drive chamando o método Drive.fake
. Por padrão, apenas o disco padrão é falsificado. No entanto, você também pode definir nomes de disco explicitamente.
import Drive from '@ioc:Adonis/Core/Drive'
// Fake default disk
Drive.fake()
// Fake local and s3
Drive.fake(['s3', 'local'])
Drive.restore
Você pode restaurar falsificações chamando o método Drive.restore
. Opcionalmente, você pode passar os nomes dos discos para restaurar, caso contrário, o disco padrão será restaurado. Ou use o método Drive.restoreAll
para restaurar todo o disco.
// Restore default disk
Drive.restore()
// Restore specific disks
Drive.restore(['s3', 'local'])
// Restore all the disks
Drive.restoreAll()
Encontrando arquivos
O método Drive.fake
retorna o objeto de unidade falsa que você pode usar para buscar ou encontrar arquivos posteriormente.
const drive = Drive.fake()
// Find if file exists
assert.isTrue(await drive.exists('avatar.jpg'))
// Assert for the file size
assert.isBelow(await drive.bytes('avatar.jpg'), 1000 * 1000 * 20)
// Assert for file contents
assert.equal(await drive.get('package.json'), JSON.stringify({}))
Hashing
Você pode falsificar o módulo Hash chamando o método Hash.fake
. Nenhum hash de senha é executado durante a falsificação, e o método hash.make
retorna o mesmo valor.
import Hash from '@ioc:Adonis/Core/Hash'
// Fake hash implementation
Hash.fake()
const hashed = await Hash.make('secret') // returns "secret"
await Hash.verify(hashed, 'secret') // returns "true"
// Restore fake
Hash.restore()
Objetos de simulação
O AdonisJS não é fornecido com nenhuma biblioteca de simulação pronta para uso. Você pode usar qualquer biblioteca de simulação do ecossistema Node.
A seguir, um pequeno exemplo demonstrando o uso do SinonJS para simular classes ES6.
export default class ExchangeService {
constructor (private baseCurrency: string) {}
public getRate(currency: string, amount: number) {
}
}
Durante os testes, você pode importar o ExchangeService
e simular o método getRate
da seguinte forma.
import { test } from '@japa/runner'
// highlight-start
import sinon from 'sinon'
import ExchangeService from 'App/Services/ExchangeService'
// highlight-end
test('transfer payment', async ({ client }) => {
// highlight-start
const mock = sinon.mock(ExchangeService.prototype)
mock
.expects('getRate')
.once()
.withArgs('INR', 600)
.returns(6)
// highlight-end
await client
.post('/transfer')
.form({ currency: 'INR', amount: 600 })
// highlight-start
mock.verify()
mock.restore()
// highlight-end
})
Solicitações de rede simuladas
Você pode usar nock para simular as solicitações de rede de saída. Como o nock funciona substituindo o http.request
do Node.js, ele funciona com quase todos os clientes HTTP, incluindo axios
e got
.
A seguir, um exemplo para simular a API charges
do Stripe.
// title: 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,
}
})
}
Agora, você pode usar o auxiliar mockStripeCharge
da seguinte forma.
import { mockStripeCharge } from 'TestHelpers/mocks'
test('complete purchase with stripe charge', async () => {
mockStripeCharge()
// Make a call to stripe API here
})