@vue/test-utils#Wrapper TypeScript Examples

The following examples show how to use @vue/test-utils#Wrapper. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.ts    From vue-storefront-1 with MIT License 6 votes vote down vote up
mountMixin = <V extends Vue>(
  component: ComponentOptions<V>,
  mountOptions: ThisTypedShallowMountOptions<V> = {},
  template = '<div />'
): Wrapper<V> => {
  const localVue = createLocalVue();

  localVue.use(Vuex);

  return shallowMount({
    template,
    mixins: [component]
  }, {
    localVue,
    ...mountOptions
  })
}
Example #2
Source File: index.ts    From vue-storefront-1 with MIT License 6 votes vote down vote up
mountMixinWithStore = <V extends Vue>(
  component: ComponentOptions<V>,
  storeOptions: object = {},
  mountOptions: ThisTypedShallowMountOptions<V> = {},
  template = '<div />'
): Wrapper<V> => {
  const localVue = createLocalVue();

  localVue.use(Vuex);

  const store = new Vuex.Store({
    ...storeOptions
  });

  return shallowMount({
    template,
    mixins: [component]
  }, {
    store,
    localVue,
    ...mountOptions
  })
}
Example #3
Source File: index.ts    From vue-reuse with MIT License 6 votes vote down vote up
export function renderComposable(
  cb: () => any,
  attachTo?: Element | string
): Wrapper<Vue> {
  return mount(
    {
      setup() {
        return cb()
      },
      render(h) {
        return h('div')
      }
    },
    { attachTo }
  )
}
Example #4
Source File: TypeaheadSearch.test.ts    From wvui with GNU General Public License v2.0 4 votes vote down vote up
describe( 'typing into input', () => {
	let onFetchStart: jest.Mock;
	let onFetchEnd: jest.Mock;
	let client: Record<string, jest.Mock>;
	let wrapper: Wrapper<Vue>;
	let input: Wrapper<Vue>;
	let fetchPromise: Promise<SearchResponse>;

	beforeEach( () => {
		onFetchStart = jest.fn();
		onFetchEnd = jest.fn();

		client = {
			fetchByTitle: jest.fn( () => {
				return {
					fetch: fetchPromise,
					abort: jest.fn()
				};
			} )
		};

		wrapper = mount( WvuiTypeaheadSearch, {
			propsData: {
				...propsData,
				client
			},
			listeners: {
				'fetch-start': onFetchStart,
				'fetch-end': onFetchEnd
			},
			slots: {
				default: defaultSlot
			}
		} );
		input = wrapper.find( '.wvui-input__input' );

		jest.useFakeTimers( 'modern' );
	} );

	afterEach( () => {
		jest.useRealTimers();
	} );

	it( 'does not show search results if the input does not have focus', async () => {
		fetchPromise = Promise.resolve( {
			query: 'test',
			results: []
		} );

		input.setValue( 'test' );
		jest.advanceTimersByTime( DEBOUNCE_INTERVAL );

		await fetchPromise;

		// Wait for Vue to flush DOM changes.
		await wrapper.vm.$nextTick();

		expect( wrapper.classes() ).not.toContain( 'wvui-typeahead-search--expanded' );
	} );

	it( 'emits `fetch-start` and `fetch-end` events when successful response', async () => {
		fetchPromise = Promise.resolve( {
			query: 'test',
			results: []
		} );

		expect( onFetchStart.mock.calls.length ).toBe( 0 );
		expect( onFetchEnd.mock.calls.length ).toBe( 0 );

		input.setValue( 'test' );
		jest.advanceTimersByTime( DEBOUNCE_INTERVAL );

		expect( onFetchStart.mock.calls.length ).toBe( 1 );
		expect( onFetchEnd.mock.calls.length ).toBe( 0 );

		await fetchPromise;

		expect( onFetchStart.mock.calls.length ).toBe( 1 );
		expect( onFetchEnd.mock.calls.length ).toBe( 1 );
	} );

	it( 'emits `fetch-start` but not `fetch-end` event when failed response', async () => {
		fetchPromise = Promise.reject( new Error( 'Network Error Test' ) );

		input.setValue( 'test' );
		jest.advanceTimersByTime( DEBOUNCE_INTERVAL );

		expect( onFetchStart.mock.calls.length ).toBe( 1 );
		expect( onFetchEnd.mock.calls.length ).toBe( 0 );

		return fetchPromise.catch( () => {
			expect( onFetchStart.mock.calls.length ).toBe( 1 );
			expect( onFetchEnd.mock.calls.length ).toBe( 0 );
		} );

	} );

	it( 'does not call search client or emit events when blank input', async () => {
		input.setValue( '  ' );
		jest.advanceTimersByTime( DEBOUNCE_INTERVAL );

		expect( onFetchStart.mock.calls.length ).toBe( 0 );
		expect( onFetchEnd.mock.calls.length ).toBe( 0 );
		expect( client.fetchByTitle.mock.calls.length ).toBe( 0 );
		expect( wrapper.vm.$data.suggestionsList ).toEqual( [ ] );
		expect( wrapper.vm.$data.searchQuery ).toEqual( '' );
	} );

	it( 'aborts the previous request when new input', async () => {
		fetchPromise = new Promise( () => {
			// No-op (represents a promise that hasn't resolved yet).
		} );

		input.setValue( 'first query' );
		jest.advanceTimersByTime( DEBOUNCE_INTERVAL );

		expect( client.fetchByTitle.mock.results[ 0 ].value.abort.mock.calls.length ).toBe( 0 );

		input.setValue( 'second query' );
		jest.advanceTimersByTime( DEBOUNCE_INTERVAL );

		expect( client.fetchByTitle.mock.results[ 0 ].value.abort.mock.calls.length ).toBe( 1 );

		input.setValue( '' );
		jest.advanceTimersByTime( DEBOUNCE_INTERVAL );

		expect( client.fetchByTitle.mock.results[ 0 ].value.abort.mock.calls.length ).toBe( 1 );
		expect( client.fetchByTitle.mock.results[ 1 ].value.abort.mock.calls.length ).toBe( 1 );
	} );
} );
Example #5
Source File: TypeaheadSearch.test.ts    From wvui with GNU General Public License v2.0 4 votes vote down vote up
describe( 'when there are search results', () => {
	let wrapper: Wrapper<Vue>;
	let input: Wrapper<Vue>;
	let inputElement: HTMLInputElement;

	const client = {
		fetchByTitle: jest.fn( () => {
			return {
				fetch: Promise.resolve( {
					query: 'test',
					results: restApiSuggestions.pages
				} ),
				abort: () => {
					// No-op
				}
			};
		} )
	};

	beforeEach( async () => {
		jest.useFakeTimers( 'modern' );

		wrapper = mount( WvuiTypeaheadSearch, {
			propsData: {
				...propsData,
				client
			},
			slots: {
				default: defaultSlot
			}
		} );

		input = wrapper.find( '.wvui-input__input' );
		inputElement = input.element as HTMLInputElement;

		await input.trigger( 'focus' );
		await input.setValue( 'test' );

		jest.advanceTimersByTime( DEBOUNCE_INTERVAL );

		await wrapper.vm.$nextTick();
	} );

	afterEach( () => {
		jest.useRealTimers();
	} );

	it( 'matches the snapshot', () => {
		expect( wrapper.element ).toMatchSnapshot();
	} );

	it( 'shows suggestions list', () => {
		const suggestionItemComponent = wrapper.findAllComponents( {
			name: 'wvui-typeahead-suggestion'
		} );

		expect( wrapper.vm.$data.isExpanded ).toBeTruthy();
		expect( wrapper.classes() ).toContain( 'wvui-typeahead-search--expanded' );
		expect( suggestionItemComponent.length ).toEqual( restApiSuggestions.pages.length );
	} );

	it( 'sets value and highlights a suggestion on key down', async () => {

		// Note well that you can't trigger keydown.foo events via Wrapper#trigger. See
		// https://github.com/vuejs/vue-test-utils/issues/1295 for discussion.
		//
		// See also https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
		// for a list of accepted values for the key options entry.
		await wrapper.trigger( 'keydown', { key: 'ArrowDown' } );

		const expectedInputElementValue = restApiSuggestions.pages[ 0 ].title;

		expect( inputElement.value ).toStrictEqual( expectedInputElementValue );

		const expectedActiveIndex = 0;

		expect( wrapper.vm.$data.suggestionActiveIndex ).toStrictEqual( expectedActiveIndex );

		// ---

		const suggestion = wrapper.findAll( '.wvui-typeahead-suggestion' )
			.at( expectedActiveIndex );

		expect( suggestion.classes() ).toContain( 'wvui-typeahead-suggestion--active' );
	} );

	it( 'highlights suggestion on mouseover', async () => {
		const suggestion1 = wrapper.findComponent( {
			name: 'wvui-typeahead-suggestion'
		} );

		await suggestion1.trigger( 'mouseover' );

		expect( suggestion1.classes() ).toContain( 'wvui-typeahead-suggestion--active' );

		// ---

		const suggestion2 = wrapper.find( '.wvui-typeahead-search__suggestions__footer' );

		await suggestion2.trigger( 'mouseover' );

		expect( suggestion1.classes() ).not.toContain( 'wvui-typeahead-suggestion--active' );
		expect( suggestion2.classes() ).toContain(
			'wvui-typeahead-search__suggestions__footer--active'
		);
	} );

	// eslint-disable-next-line max-len
	it( 'wraps around to the footer suggestion when the user immediately presses up on the keyboard', async () => {
		const footerClassName = 'wvui-typeahead-search__suggestions__footer';
		const footer = wrapper.find( `.${footerClassName}` );

		await wrapper.trigger( 'keydown', { key: 'ArrowUp' } );

		expect( inputElement.value ).toBe( 'test' );
		expect( footer.classes() ).toContain( `${footerClassName}--active` );
	} );

	// eslint-disable-next-line max-len
	it( 'wraps around to the top of the suggestions list when navigating with the keyboard', async () => {
		await wrapper.trigger( 'keydown', { key: 'ArrowUp' } );
		await wrapper.trigger( 'keydown', { key: 'ArrowUp' } );
		await wrapper.trigger( 'keydown', { key: 'ArrowDown' } );
		await wrapper.trigger( 'keydown', { key: 'ArrowDown' } );

		expect( inputElement.value ).toStrictEqual( 'test' );

		let expectedActiveIndex = restApiSuggestions.pages.length + 1;

		expect( wrapper.vm.$data.suggestionActiveIndex ).toStrictEqual( expectedActiveIndex );

		// ---

		await wrapper.trigger( 'keydown', { key: 'ArrowDown' } );

		expect( inputElement.value ).toStrictEqual( restApiSuggestions.pages[ 0 ].title );

		expectedActiveIndex = 0;

		expect( wrapper.vm.$data.suggestionActiveIndex ).toStrictEqual( expectedActiveIndex );
	} );

	it( 'responds when the user clicks a suggestion', async () => {
		const suggestionComponent = wrapper.findComponent( {
			name: 'wvui-typeahead-suggestion'
		} );

		await suggestionComponent.trigger( 'click' );

		// We expect:

		// 1. The list of suggestions to be hidden
		expect( wrapper.vm.$data.isExpanded ).toBeFalsy();
		expect( wrapper.classes() ).not.toContain( 'wvui-typeahead-search--expanded' );

		// ---

		// 2. The input's value to have been set the suggestion's title
		const suggestion = restApiSuggestions.pages[ 0 ];

		expect( inputElement.value ).toBe( suggestion.title ); // 2
	} );

	it( 'responds when the user clicks suggestions footer', async () => {
		const suggestionComponent = wrapper.find( '.wvui-typeahead-search__suggestions__footer' );

		await suggestionComponent.trigger( 'click' );

		// We expect:

		// 1. The list of suggestions to be hidden
		expect( wrapper.vm.$data.isExpanded ).toBeFalsy();
		expect( wrapper.classes() ).not.toContain( 'wvui-typeahead-search--expanded' );

		// ---

		// 2. The input's value set to the search query
		expect( inputElement.value ).toBe( 'test' );

		// 3. The link's href needs to be maintained after the component's click
		// callbacks have executed so the browser can navigate to it.
		expect( suggestionComponent.attributes( 'href' ) ).toContain( 'search=test' );
		expect( suggestionComponent.attributes( 'href' ) ).toContain( 'fulltext=1' );
	} );

	it( 'hides the suggestions list when the user presses the escape key', async () => {
		await wrapper.trigger( 'keydown', { key: 'Escape' } );

		expect( wrapper.vm.$data.isExpanded ).toBeFalsy();
		expect( wrapper.classes() ).not.toContain( 'wvui-typeahead-search--expanded' );
	} );

	it( 'hides the suggestions list when the user clears the input', async () => {
		await input.setValue( '' );

		jest.advanceTimersByTime( DEBOUNCE_INTERVAL );

		await wrapper.vm.$nextTick();

		// The suggestions list should be hidden
		expect( wrapper.vm.$data.isExpanded ).toBeFalsy();
		expect( wrapper.classes() ).not.toContain( 'wvui-typeahead-search--expanded' );

		// ... and there shouldn't be any highlighted suggestions.
		expect( wrapper.vm.$data.suggestionActiveIndex ).toBe( -1 );
		expect( wrapper.find( '.wvui-typeahead-suggestion--active' ).exists() ).toBeFalsy();

		// ---

		await wrapper.trigger( 'keydown', { key: 'ArrowDown' } );

		expect( wrapper.vm.$data.suggestionActiveIndex ).toBe( -1 );
		expect( wrapper.find( '.wvui-typeahead-suggestion--active' ).exists() ).toBeFalsy();
	} );

	describe( 'when the form is submitted', () => {
		const { location } = window;
		const assignMock = jest.fn();

		beforeAll( () => {
			// eslint-disable-next-line
			delete (window as any).location;
			// eslint-disable-next-line
			(window as any).location = { assign: assignMock };
		} );

		afterAll( () => {
			window.location = location;
		} );

		it( 'navigates to default url when nothing is selected', async () => {
			wrapper.find( 'form' ).trigger( 'submit' );

			expect( assignMock ).toHaveBeenCalledTimes( 0 );
		} );

		it( 'navigates to default url when suggestion is selected', async () => {
			await wrapper.trigger( 'keydown', { key: 'ArrowDown' } );
			wrapper.find( 'form' ).trigger( 'submit' );

			expect( assignMock ).toHaveBeenCalledTimes( 0 );
		} );

		it( 'manually navigates to search results when the footer is selected', async () => {
			await wrapper.trigger( 'keydown', { key: 'ArrowUp' } );
			wrapper.find( 'form' ).trigger( 'submit' );

			expect( assignMock ).toHaveBeenCalledTimes( 1 );
		} );
	} );
} );
Example #6
Source File: useRequest.spec.ts    From vue-reuse with MIT License 4 votes vote down vote up
describe('test use async ', () => {
  let wrapper: Wrapper<Vue>
  afterEach(() => {
    wrapper.destroy()
  })

  test('test request ', async () => {
    wrapper = renderComposable(() =>
      useRequest(Fetch, {
        defaultParams: [1]
      })
    )
    const { vm } = wrapper
    // create
    expect(vm.$data.loading).toBeUndefined()
    expect(vm.$data.params).toBeUndefined()
    expect(vm.$data.data).toBeUndefined()
    // after mount begin request
    await vm.$nextTick()
    expect(vm.$data.loading).toBe(true)
    expect(vm.$data.params).toEqual([1])
    expect(vm.$data.data).toBeUndefined()
    // after request back
    await waitTime(110)
    expect(vm.$data.loading).toBe(false)
    expect(vm.$data.params).toEqual([1])
    expect(vm.$data.data).toEqual(1)
  })

  test(`test request manaul `, async () => {
    wrapper = renderComposable(() =>
      useRequest(Fetch, {
        defaultData: 1,
        manual: true
      })
    )
    const { vm } = wrapper
    // after mount
    await vm.$nextTick()
    expect(vm.$data.loading).toBe(false)
    expect(vm.$data.params).toEqual([])
    expect(vm.$data.data).toBe(1)
    // start request
    vm.$data.run(3)
    expect(vm.$data.loading).toBe(true)
    expect(vm.$data.params).toEqual([3])
    expect(vm.$data.data).toBe(1)
    await waitTime(110)
    expect(vm.$data.loading).toBe(false)
    expect(vm.$data.params).toEqual([3])
    expect(vm.$data.data).toBe(3)
  })

  test(`test request parallel `, async () => {
    wrapper = renderComposable(() =>
      useRequest(parallelFetch, {
        manual: true,
        fetchKey: (p) => p.key
      })
    )
    const { vm } = wrapper
    // after mount
    await vm.$nextTick()
    expect(vm.$data.loading).toBe(false)
    expect(vm.$data.params).toEqual([])
    expect(vm.$data.data).toBeUndefined()
    // start some request
    vm.$data.run({ key: '1', res: 1 })
    expect(vm.$data.fetches['1'].loading).toBe(true)
    expect(vm.$data.fetches['1'].params).toEqual([{ key: '1', res: 1 }])
    expect(vm.$data.fetches['1'].data).toBeUndefined()
    vm.$data.run({ key: '2', res: 2 })
    expect(vm.$data.fetches['2'].loading).toBe(true)
    expect(vm.$data.fetches['2'].params).toEqual([{ key: '2', res: 2 }])
    expect(vm.$data.fetches['2'].data).toBeUndefined()
    // after request
    await waitTime(110)
    expect(vm.$data.fetches['1'].loading).toBe(false)
    expect(vm.$data.fetches['1'].params).toEqual([{ key: '1', res: 1 }])
    expect(vm.$data.fetches['1'].data).toBe(1)

    expect(vm.$data.fetches['2'].loading).toBe(false)
    expect(vm.$data.fetches['2'].params).toEqual([{ key: '2', res: 2 }])
    expect(vm.$data.fetches['2'].data).toBe(2)
    // re request
    vm.$data.run({ key: '1', res: 10 })
    vm.$data.run({ key: '2', res: 20 })
    await waitTime(110)
    expect(vm.$data.fetches['1'].data).toBe(10)
    expect(vm.$data.fetches['2'].data).toBe(20)
  })

  test(`test request formatResult `, async () => {
    wrapper = renderComposable(() =>
      useRequest(Fetch, {
        defaultParams: [1],
        formatResult: (res) => ({ res }),
        defaultData: { res: 2 }
      })
    )
    const { vm } = wrapper
    await vm.$nextTick()
    expect(vm.$data.loading).toBe(true)
    expect(vm.$data.params).toEqual([1])
    expect(vm.$data.data).toEqual({ res: 2 })
    // after request
    await waitTime(110)
    expect(vm.$data.loading).toBe(false)
    expect(vm.$data.params).toEqual([1])
    expect(vm.$data.data).toEqual({ res: 1 })
  })

  test(`test request debouce `, async () => {
    wrapper = renderComposable(() =>
      useRequest(Fetch, {
        manual: true,
        debounceTime: 50
      })
    )
    const { vm } = wrapper
    await vm.$nextTick()
    vm.$data.run(1)
    vm.$data.run(2)
    vm.$data.run(3)
    vm.$data.run(4)
    await waitTime(160)
    expect(vm.$data.data).toBe(4)
  })

  test(`test request throttle `, async () => {
    wrapper = renderComposable(() =>
      useRequest(Fetch, {
        manual: true,
        throttleTime: 50
      })
    )
    const { vm } = wrapper
    await vm.$nextTick()
    vm.$data.run(1)
    vm.$data.run(2)
    vm.$data.run(3)
    vm.$data.run(4)
    await waitTime(160)
    expect(vm.$data.data).toBe(4)
  })

  test(`test request polling `, async () => {
    const onSuccess = jest.fn()
    wrapper = renderComposable(() =>
      useRequest(Fetch, {
        manual: true,
        pollingTime: 50,
        onSuccess
      })
    )
    const { vm } = wrapper
    await vm.$nextTick()
    vm.$data.run(1)
    // (100 + 50) * 2
    await waitTime(310)
    expect(onSuccess).toBeCalledTimes(2)
    // cancel polling
    vm.$data.cancel()
    await waitTime(310)
    expect(onSuccess).toBeCalledTimes(2)
  })

  test(`test loading delay `, async () => {
    wrapper = renderComposable(() =>
      useRequest(Fetch, {
        loadingDelay: 20,
        defaultParams: [1]
      })
    )
    const { vm } = wrapper
    // after mount
    await vm.$nextTick()
    expect(vm.$data.loading).toBeFalsy()
    // before delay
    await waitTime(10)
    expect(vm.$data.loading).toBeFalsy()
    // after delay
    await waitTime(30)
    expect(vm.$data.loading).toBeTruthy()
    // after request
    await waitTime(70)
    expect(vm.$data.loading).toBeFalsy()
    expect(vm.$data.data).toBe(1)
  })

  test(`test request error `, async () => {
    const onError = jest.fn()
    wrapper = renderComposable(() =>
      useRequest(FetchError, {
        manual: true,
        onError
      })
    )
    const { vm } = wrapper
    await vm.$nextTick()
    expect(vm.$data.error).toBeUndefined()
    await vm.$data.run(1).catch((err: Error) => {
      expect(err).toBe(
        `useRequest has caught the exception, if you need to handle the exception yourself, you can set options.throwOnError to true.`
      )
    })
    await vm.$nextTick()
    expect(onError).toBeCalled()
    expect(onError).toBeCalledWith(1, [1])
    expect(vm.$data.error).toBe(1)
  })

  test(`test request error throw `, async () => {
    const onError = jest.fn()
    wrapper = renderComposable(() =>
      useRequest(FetchError, {
        manual: true,
        onError,
        throwOnError: true
      })
    )
    const { vm } = wrapper
    await vm.$nextTick()
    expect(vm.$data.error).toBeUndefined()
    await vm.$data.run(2).catch((err: Error) => {
      expect(err).toBe(2)
    })
    await vm.$nextTick()
    expect(onError).toBeCalled()
    expect(onError).toBeCalledWith(2, [2])
    expect(vm.$data.error).toBe(2)
  })

  test(`test request reset `, async () => {
    wrapper = renderComposable(() =>
      useRequest(Fetch, {
        manual: true
      })
    )
    const { vm } = wrapper
    await vm.$nextTick()
    expect(vm.$data.data).toBeUndefined()
    await vm.$data.run(2)
    expect(vm.$data.data).toBe(2)
    vm.$data.reset()
    await vm.$nextTick()
    expect(vm.$data.data).toBe(2)
    expect(vm.$data.fetches).toEqual({})
  })

  test(`test request cache `, async () => {
    const CacheKey = 'test_cache'
    const DefaultKey = `vue_reuse_request_default_fetch_key`
    wrapper = renderComposable(() =>
      useRequest(Fetch, {
        defaultParams: [1],
        cacheKey: CacheKey,
        cacheTime: 200
      })
    )
    const { vm } = wrapper
    // after mount
    await vm.$nextTick()
    expect(vm.$data.loading).toBeTruthy()
    expect(vm.$data.params).toEqual([1])
    expect(vm.$data.data).toBeUndefined()
    await waitTime(110)
    expect(vm.$data.loading).toBeFalsy()
    expect(vm.$data.params).toEqual([1])
    expect(vm.$data.data).toBe(1)
    vm.$destroy()
    const cached = getCache(CacheKey)
    expect(cached.data?.fetchKey).toBe(DefaultKey)
    expect(cached.data?.fetches[DefaultKey].data).toBe(1)
    // in any where request again cache data will be initial
    wrapper = renderComposable(() =>
      useRequest(Fetch, {
        defaultParams: [2],
        cacheKey: CacheKey,
        cacheTime: 200
      })
    )
    const { vm: vm2 } = wrapper
    // after mount
    await vm2.$nextTick()
    expect(vm2.$data.loading).toBeTruthy()
    expect(vm2.$data.params).toEqual([2])
    expect(vm2.$data.data).toBe(1)
    // after request
    await waitTime(110)
    expect(vm2.$data.loading).toBeFalsy()
    expect(vm2.$data.params).toEqual([2])
    expect(vm2.$data.data).toBe(2)
    // after clear cache
    await waitTime(100)
    const cached2 = getCache(CacheKey)
    expect(cached2.data?.fetchKey).toBeUndefined()
    expect(cached2.data?.fetches).toBeUndefined()
  })

  test(`test custom request method `, async () => {
    wrapper = renderComposable(() =>
      useRequest('1', {
        requestMethod: customRequest2,
        defaultParams: ['2', '3']
      })
    )
    const { vm } = wrapper
    await vm.$nextTick()
    expect(vm.$data.loading).toBe(true)
    expect(vm.$data.params).toEqual(['2', '3'])
    expect(vm.$data.data).toBeUndefined()
    await waitTime(110)
    expect(vm.$data.loading).toBe(false)
    expect(vm.$data.params).toEqual(['2', '3'])
    expect(vm.$data.data).toBe('123')
  })

  test(`test custom request method functional service `, async () => {
    const url = (p: string) => p
    wrapper = renderComposable(() =>
      useRequest(url, {
        requestMethod: customRequest,
        defaultParams: ['1']
      })
    )
    const { vm } = wrapper
    await vm.$nextTick()
    expect(vm.$data.loading).toBe(true)
    expect(vm.$data.params).toEqual(['1'])
    expect(vm.$data.data).toBeUndefined()
    await waitTime(110)
    expect(vm.$data.loading).toBe(false)
    expect(vm.$data.params).toEqual(['1'])
    expect(vm.$data.data).toBe('1')
  })

  test(`test custom request method object service `, async () => {
    const customRequest = ({ url }: { url: string }) =>
      new Promise<string>((resolve) => {
        setTimeout(() => {
          resolve(url)
        }, 100)
      })
    const url = (url: string) => ({ url })
    wrapper = renderComposable(() =>
      useRequest(url, {
        requestMethod: customRequest,
        defaultParams: ['1']
      })
    )
    const { vm } = wrapper
    await vm.$nextTick()
    expect(vm.$data.loading).toBe(true)
    expect(vm.$data.params).toEqual(['1'])
    expect(vm.$data.data).toBeUndefined()
    await waitTime(110)
    expect(vm.$data.loading).toBe(false)
    expect(vm.$data.params).toEqual(['1'])
    expect(vm.$data.data).toBe('1')
    vm.$destroy()
    // object
    wrapper = renderComposable(() =>
      useRequest(
        { url: '1' },
        {
          requestMethod: customRequest
        }
      )
    )
    const { vm: vm1 } = wrapper
    await vm1.$nextTick()
    expect(vm1.$data.loading).toBe(true)
    expect(vm1.$data.params).toEqual([])
    expect(vm1.$data.data).toBeUndefined()
    await waitTime(110)
    expect(vm1.$data.loading).toBe(false)
    expect(vm1.$data.params).toEqual([])
    expect(vm1.$data.data).toBe('1')
  })

  test(`test global fetch `, async () => {
    wrapper = renderComposable(() =>
      useRequest('1', {
        manual: true
      })
    )
    const { vm } = wrapper
    await vm.$nextTick()
    expect(vm.$data.data).toBeUndefined()
    await vm.$data.run()
    expect(vm.$data.data).toBe('1')
    await vm.$data.run({ error: 'error' }).catch((err: Error) => {
      expect(err).toBe(
        `useRequest has caught the exception, if you need to handle the exception yourself, you can set options.throwOnError to true.`
      )
    })
  })
})