முக்கிய உள்ளடக்கத்திற்கு செல்க

Mocking

டெஸ்டுகளை எழுதும்போது, நீங்கள் இன்டெர்னல் அல்லது எக்ஸ்டெர்னல் சர்வீஸின் "போலி" பதிப்பை உருவாக்க வேண்டும். இது பொதுவாக மாக்கிங் என்று குறிப்பிடப்படுகிறது. WebdriverIO உங்களுக்கு உதவ பயன்பாட்டு செயல்பாடுகளை வழங்குகிறது. அதை அணுக import { fn, spyOn, mock, unmock } from '@wdio/browser-runner' இறக்குமதி செய்யலாம். API docs இல் இருக்கும் மாக் செய்யும் பயன்பாடுகள்பற்றிய கூடுதல் தகவலைப் பார்க்கவும்.

செயல்பாடுகள்

சில செயல்பாடு ஹேண்ட்லர்கள் உங்கள் காம்போனென்ட் சோதனைகளின் ஒரு பகுதியாக அழைக்கப்படுகிறதா என்பதைச் சரிபார்க்க, @wdio/browser-runner மாட்யூல் மாக் செய்யும் ப்ரிமிட்டிவ்களை ஏற்றுமதி செய்கிறது, இந்தச் செயல்பாடுகள் அழைக்கப்பட்டிருந்தால், நீங்கள் சோதிக்க பயன்படுத்தலாம். இந்த மெத்தெடுகளை நீங்கள் இறக்குமதி செய்யலாம்:

import { fn, spy } from '@wdio/browser-runner'

fn ஐ இறக்குமதி செய்வதன் மூலம், அதன் செயல்பாட்டைக் கண்காணிக்க உளவு செயல்பாட்டை (mock) உருவாக்கலாம் மற்றும் spyOn மூலம் ஏற்கனவே உருவாக்கப்பட்ட ஆப்ஜெக்ட்டின் மீது ஒரு மெத்தடை கண்காணிக்கலாம்.

முழு உதாரணத்தையும் Component Testing Example இல் காணலாம் களஞ்சியம்.

import React from 'react'
import { $, expect } from '@wdio/globals'
import { fn } from '@wdio/browser-runner'
import { Key } from 'webdriverio'
import { render } from '@testing-library/react'

import LoginForm from '../components/LoginForm'

describe('LoginForm', () => {
it('should call onLogin handler if username and password was provided', async () => {
const onLogin = fn()
render(<LoginForm onLogin={onLogin} />)
await $('input[name="username"]').setValue('testuser123')
await $('input[name="password"]').setValue('s3cret')
await browser.keys(Key.Enter)

/**
* verify the handler was called
*/
expect(onLogin).toBeCalledTimes(1)
expect(onLogin).toBeCalledWith(expect.equal({
username: 'testuser123',
password: 's3cret'
}))
})
})

WebdriverIO @vitest/spy மீண்டும் ஏற்றுமதி செய்கிறது, இது WebdriverIOs expect மேட்ச்சர்களுடன் பயன்படுத்தக்கூடிய இலகுரக ஜெஸ்ட் இணக்கமான உளவு செயலாக்கமாகும். இந்த மாக் செயல்பாடுகள்பற்றிய கூடுதல் ஆவணங்களை Vitest project pageஇல் காணலாம்.

நிச்சயமாக, நீங்கள் வேறு எந்த உளவு பிரமேஒர்க்கையும் நிறுவலாம் மற்றும் இறக்குமதி செய்யலாம், எ.கா. SinonJS, பிரௌசர் என்விரான்மென்டை ஆதரிக்கும் வரை.

தொகுதிகள்

லோக்கல் தொகுதிகளை மாக் செய்யவும் அல்லது வேறுசில கோடில் செயல்படுத்தப்படுகின்ற மூன்றாம் தரப்பு-லைப்ரரிகளை கண்காணிக்கவும், ஆர்குமென்டுகளை டெஸ்ட் செய்யவும், வெளியீடு செய்யவும் அல்லது அதன் செயலாக்கத்தை மீண்டும் அறிவிக்கவும் அனுமதிக்கிறது.

செயல்பாடுகளை மாக் செய்ய இரண்டு வழிகள் உள்ளன: டெஸ்ட் கோடில் பயன்படுத்த ஒரு மாக் செயல்பாட்டை உருவாக்குவதன் மூலம் அல்லது ஒரு தொகுதி சார்புநிலையை ஓவர்ரைடு செய்ய ஒரு மேனுவல் மாக் எழுதுவதன் மூலம்.

பைல் இறக்குமதிகளை மாக் செய்தல்

ஒரு க்ளிக்கைக் கையாள ஒரு பைலிலிருந்து ஒரு பயன்பாட்டு முறையை எங்கள் காம்போனென்ட் இறக்குமதி செய்கிறது என்று கற்பனை செய்து கொள்வோம்.

export function handleClick () {
// handler implementation
}

எங்கள் காம்போனென்டுகளில் கிளிக் கையாளுதல் பின்வருமாறு பயன்படுத்தப்படுகிறது:

import { handleClick } from './utils.js'

@customElement('simple-button')
export class SimpleButton extends LitElement {
render() {
return html`<button @click="${handleClick}">Click me!</button>`
}
}

utils.js இலிருந்து handleClick மாக் செய்ய, எங்கள் டெஸ்டில் mock மெத்தடைப் பின்வருமாறு பயன்படுத்தலாம்:

import { expect, $ } from '@wdio/globals'
import { mock, fn } from '@wdio/browser-runner'
import { html, render } from 'lit'

import { SimpleButton } from './LitComponent.ts'
import { handleClick } from './utils.js'

/**
* mock named export "handleClick" of `utils.ts` file
*/
mock('./utils.ts', () => ({
handleClick: fn()
}))

describe('Simple Button Component Test', () => {
it('call click handler', async () => {
render(html`<simple-button />`, document.body)
await $('simple-button').$('>>> button').click()
expect(handleClick).toHaveBeenCalledTimes(1)
})
})

மாக்கிங் சார்புகள்

எங்களின் API இலிருந்து பயனர்களைப் பெறும் ஒரு கிளாஸ் எங்களிடம் உள்ளது என்று வைத்துக்கொள்வோம். API ஐ அழைக்கக் கிளாஸ் axios ஐப் பயன்படுத்துகிறது, பின்னர் அனைத்து பயனர்களையும் உள்ளடக்கிய டேட்டா ஆட்ரிபூட் வழங்குகிறது:

import axios from 'axios';

class Users {
static all() {
return axios.get('/users.json').then(resp => resp.data)
}
}

export default Users

இப்போது, API ஐத் தாக்காமல் இந்த டெஸ்ட் செய்வதற்காக (இதனால் மெதுவான மற்றும் பலவீனமான டெஸ்டுகளை உருவாக்குதல்), நாம் mock(...) செயல்பாட்டைப் பயன்படுத்தி, axios தொகுதியைத் தானாகவே மாக் செய்யலாம்.

தொகுதியை நாம் மாக் செய்தவுடன், mockResolvedValue get. ஐப் பெறுங்கள், இது எங்கள் டெஸ்டிற்கு எதிராக நாங்கள் உறுதிப்படுத்த விரும்பும் டேட்டாவை வழங்கும். உண்மையில், போலியான பதிலை வழங்க axios.get('/users.json') வேண்டும் என்று கூறுகிறோம்.

import axios from 'axios'; // imports defined mock
import { mock, fn } from '@wdio/browser-runner'

import Users from './users.js'

/**
* mock default export of `axios` dependency
*/
mock('axios', () => ({
default: {
get: fn()
}
}))

describe('User API', () => {
it('should fetch users', async () => {
const users = [{name: 'Bob'}]
const resp = {data: users}
axios.get.mockResolvedValue(resp)

// or you could use the following depending on your use case:
// axios.get.mockImplementation(() => Promise.resolve(resp))

const data = await Users.all()
expect(data).toEqual(users)
})
})

பகுதிகள்

ஒரு தொகுதியின் துணைக்குழுக்கள் மாக் செய்யப்படலாம் மற்றும் மீதமுள்ள தொகுதிகள் அவற்றின் உண்மையான செயலாக்கத்தை வைத்திருக்க முடியும்:

export const foo = 'foo';
export const bar = () => 'bar';
export default () => 'baz';

The original module will be passed into the mock factory which you can use to e.g. partially mock a dependency:

import { mock, fn } from '@wdio/browser-runner'
import defaultExport, { bar, foo } from './foo-bar-baz.js';

mock('./foo-bar-baz.js', async (originalModule) => {
// Mock the default export and named export 'foo'
// and propagate named export from the original module
return {
__esModule: true,
...originalModule,
default: fn(() => 'mocked baz'),
foo: 'mocked foo',
}
})

describe('partial mock', () => {
it('should do a partial mock', () => {
const defaultExportResult = defaultExport();
expect(defaultExportResult).toBe('mocked baz');
expect(defaultExport).toHaveBeenCalled();

expect(foo).toBe('mocked foo');
expect(bar()).toBe('bar');
})
})

மேனுவல் மாக்ஸ்

__mocks__/ (automockDir விருப்பத்தையும் பார்க்கவும்) துணை டைரக்டரியில் ஒரு தொகுதியை எழுதுவதன் மூலம் மேனுவல் மாக்குகள் வரையறுக்கப்படுகின்றன. நீங்கள் மாக் செய்யும் தொகுதி ஒரு நோடு தொகுதியாக இருந்தால் (எ.கா: lodash), அந்த மாக் __mocks__ டைரக்டரியில் வைக்கப்பட வேண்டும் மற்றும் தானாகவே மாக் செய்யப்படும். mock('module_name')வெளிப்படையாக அழைக்க வேண்டிய அவசியம் இல்லை.

ஸ்கோப் செய்யப்பட்ட தொகுதிகள் (ஸ்கோப்டு பேக்கேஜ்கள் என்றும் அழைக்கப்படுகின்றன) டைரக்டரி அமைப்பில் ஒரு பைலை உருவாக்குவதன் மூலம் மாக் செய்யப்படலாம், இது ஸ்கோப்டு தொகுதியின் பெயருடன் பொருந்த வேண்டும். எடுத்துக்காட்டாக, @scope/project-nameஎனப்படும் ஸ்கோப் தொகுதியை மாக் செய்ய, __mocks__/@scope/project-name.jsஇல் ஒரு பைலை உருவாக்கவும், அதன்படி @scope/ டைரக்டரியை உருவாக்கவும்.

.
├── config
├── __mocks__
│ ├── axios.js
│ ├── lodash.js
│ └── @scope
│ └── project-name.js
├── node_modules
└── views

கொடுக்கப்பட்ட தொகுதிக்கு ஒரு மேனுவல் மாக் இருக்கும்போது, WebdriverIO mock('moduleName')வெளிப்படையாக அழைக்கும்போது அந்தத் தொகுதியைப் பயன்படுத்தும். இருப்பினும், automock true என அமைக்கப்படும்போது, mock('moduleName') அழைக்கப்படாவிட்டாலும், தானாக உருவாக்கப்பட்ட மாக்கிற்கு பதிலாகக் மேனுவல் மாக் செயல்படுத்தல் பயன்படுத்தப்படும். இந்த நடத்தையிலிருந்து விலக, உண்மையான தொகுதிச் செயலாக்கத்தைப் பயன்படுத்த வேண்டிய டெஸ்டுகளில் unmock('moduleName') நீங்கள் வெளிப்படையாக அழைக்க வேண்டும், எ.கா.:

import { unmock } from '@wdio/browser-runner'

unmock('lodash')

Hoisting

பிரௌசரில் மாக் செய்வதைப் பெறுவதற்காக, WebdriverIO டெஸ்ட் பைல்களை மீண்டும் எழுதுகிறது மற்றும் எல்லாவற்றிற்கும் மேலாக மாக் அழைப்புகளை உயர்த்துகிறது (Jest இல் ஏற்றுதல் பிரச்சனையில் this blog post ஐயும் பார்க்கவும்). மாக் ரிசல்வரில் நீங்கள் வேறியபல்ஸுகளை அனுப்பும் வழியை இது கட்டுப்படுத்துகிறது, எ.கா.:

import dep from 'dependency'
const variable = 'foobar'

/**
* ❌ this fails as `dep` and `variable` are not defined inside the mock resolver
*/
mock('./some/module.ts', () => ({
exportA: dep,
exportB: variable
}))

இதைச் சரிசெய்ய, ரிசல்வருக்குள் பயன்படுத்தப்படும் அனைத்து வேறியபல்ஸுகளையும் நீங்கள் வரையறுக்க வேண்டும், எ.கா.:

/**
* ✔️ this works as all variables are defined within the resolver
*/
mock('./some/module.ts', async () => {
const dep = await import('dependency')
const variable = 'foobar'

return {
exportA: dep,
exportB: variable
}
})

கோரிக்கை

மாக் செய்யும் பிரௌசர் கோரிக்கைகளை நீங்கள் தேடுகிறீர்களானால், எ.கா. API அழைப்புகள், Request Mock and Spies பகுதிக்குச் செல்லவும்.

Welcome! How can I help?

WebdriverIO AI Copilot