sheremet-va/vi-fetch

Invalid Chai property: toHaveFetched

atuttle opened this issue · 1 comments

I'm running into the same issue as #8 while trying to use Vite, Vitest, and vi-fetch -- but the difference is that I'm trying to create a TS library and not using SvelteKit.

Here's my vite.config.ts:

/// <reference types="vitest" />
import { defineConfig } from 'vite';

export default defineConfig({
	build: {
		lib: {
			entry: './lib/main.ts',
			name: 'my_lib',
			fileName: 'root',
		},
	},
	test: {
		setupFiles: 'vitest.setup.ts',
		includeSource: ['src/**/*.{js,ts}'],
	},
	define: {
		// this causes vite to strip out in-source tests for prod builds
		// https://vitest.dev/guide/in-source.html#production-build
		'import.meta.vitest': 'undefined',
	},
});

And this is my vitest.setup.ts:

import 'vi-fetch/setup';

I really thought this was going to work, but it's not. Still getting the same error message:

Invalid Chai property: toHaveFetched

I'm trying to use in-source testing, so here's a sample source file:

import 'vi-fetch/setup';
import { mockFetch } from 'vi-fetch';

import fetch from 'node-fetch';
import { z } from 'zod';

const IQ_CONFIG_URL = process.env?.IQ_CONFIG_URL ?? 'https://example.com';

export async function getCustomers(): Promise<string[]> {
	const customersResult = await fetch(`${IQ_CONFIG_URL}/list/customers`);
	if (!customersResult.ok) throw new Error(`Failed to load customers list: ${customersResult.statusText}`);
	const customers = await customersResult.json();
	const customerListSchema = z.array(z.string());
	return customerListSchema.parse(customers);
}

if (import.meta.vitest) {
	const { afterEach, it, expect, describe, vi } = import.meta.vitest;

	describe('getCustomers', () => {
		afterEach(() => {
			vi.restoreAllMocks();
			mockFetch.clearAll();
		});

		it('should return a promise for an array of strings', async () => {
			process.env.IQ_CONFIG_URL = 'test-config-hostname';
			const expected = ['a', 'b', 'c'];
			const mock = mockFetch('GET', 'test-config-hostname/list/customers').willResolve(expected);
			let actual;
			expect(async () => {
				actual = await getCustomers();
				console.log(actual);
			}).not.toThrow();
			expect(mock).toHaveFetched(expected);
		});
	});
}

Library adds matchers only if expect is globally available. If you don't have it available globally, you need to add matchers manually:

import { declareFetchAssertions } from 'vi-fetch'
import { expect } from 'vitest'

declareFetchAssertions(expect)