使用CreateRemixStub与Vitest测试组件时遇"Expression Expected"错误
我基于Remix Run开发Shopify Hydrogen v2项目,为AddToFavoritesButton组件编写测试时,使用createRemixStub模拟隔离的Action来验证API与渲染逻辑,但执行npx vitest运行测试时,出现"Expression Expected"错误,错误截图如下:
以下是相关文件代码:
components/AddToFavoritesButton.jsx
import React, {useCallback} from 'react'; import {useFetcher} from '@remix-run/react'; export default function AddToFavoritesButton({ product_id, customer_id, isFavoriteProduct, }) { const fetcher = useFetcher(); const addToFavorites = useCallback(() => { fetcher.submit( {intent: 'add-to-favorites', product_id, customer_id}, {method: 'post'}, ); }, [fetcher, product_id, customer_id]); const removeFromFavorites = useCallback(() => { fetcher.submit( {intent: 'remove-from-favorites', product_id, customer_id}, {method: 'post'}, ); }, [fetcher, product_id, customer_id]); return ( <> {isFavoriteProduct ? ( <button onClick={removeFromFavorites}>Remove from favorites</button> ) : ( <button onClick={addToFavorites}>Add to favorites</button> )} </> ); }
tests/favorite-button.test.js
import React from 'react'; import {render, waitFor, screen, fireEvent} from '@testing-library/react'; import {createRemixStub} from '@remix-run/testing'; import AddToFavoritesButton from '../app/components/AddToFavoritesButton'; import {describe, expect, it, beforeEach, afterEach, vi} from 'vitest'; // Mocking useFetcher from @remix-run/react vi.mock('@remix-run/react', () => { return { useFetcher: vi.fn().mockReturnValue({state: 'idle'}), }; }); // Simulate the FavoriteProduct module's methods const FavoriteProduct = { saveFavorite: vi.fn().mockResolvedValue({success: true}), deleteFavorite: vi.fn().mockResolvedValue({success: true}), }; const fakeProduct = { product_id: '123', customer_id: 'abc', isFavoriteProduct: false, }; describe('AddToFavoritesButton', () => { let RemixStub; beforeEach(() => { RemixStub = createRemixStub([ { path: '/', element: <FavoriteProductTest />, loader: () => fakeProduct, }, { path: '/favorites', action: async ({request}) => { const formData = await request.formData(); const intent = formData.get('intent'); if (intent === 'add-to-favorites') { fakeProduct.isFavoriteProduct = true; await FavoriteProduct.saveFavorite( formData.get('product_id'), formData.get('customer_id'), ); } else if (intent === 'remove-from-favorites') { fakeProduct.isFavoriteProduct = false; await FavoriteProduct.deleteFavorite( formData.get('product_id'), formData.get('customer_id'), ); } return null; }, }, ]); }); function FavoriteProductTest() { const {product_id, customer_id, isFavoriteProduct} = fakeProduct; return ( <AddToFavoritesButton product_id={product_id} customer_id={customer_id} isFavoriteProduct={isFavoriteProduct} /> ); } afterEach(() => { vi.clearAllMocks(); fakeProduct.isFavoriteProduct = false; }); it('should add to favorites', async () => { render(<RemixStub initialEntries={['/']} />); fireEvent.click(screen.getByText('Add to favorites')); expect(FavoriteProduct.saveFavorite).toHaveBeenCalledWith( fakeProduct.product_id, fakeProduct.customer_id, ); await waitFor(() => expect(screen.getByText('Remove from favorites')).toBeInTheDocument(), ); expect(fakeProduct.isFavoriteProduct).toBe(true); }); });
vitest.config.js
import {defineConfig} from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [react()], test: { environment: 'jsdom', globals: true, setupFiles: './setup-tests.js', // if you have a setup file }, });
setup-tests.js
import '@testing-library/jest-dom';
package.json
{ "name": "hydrogen-certification", "private": true, "sideEffects": false, "version": "2024.4.4", "type": "module", "scripts": { "build": "shopify hydrogen build --codegen", "dev": "shopify hydrogen dev --codegen", "preview": "npm run build && shopify hydrogen preview", "lint": "eslint --no-error-on-unmatched-pattern --ext .js,.ts,.jsx,.tsx .", "codegen": "shopify hydrogen codegen" }, "prettier": "@shopify/prettier-config", "dependencies": { "@remix-run/react": "^2.8.0", "@remix-run/server-runtime": "^2.8.0", "@remix-run/testing": "^2.9.2", "@shopify/cli": "3.59.2", "@shopify/cli-hydrogen": "^8.0.4", "@shopify/hydrogen": "2024.4.2", "@shopify/remix-oxygen": "^2.0.4", "@testing-library/jest-dom": "^6.4.6", "@testing-library/react": "^16.0.0", "@vitejs/plugin-react": "^4.3.1", "axios": "^1.7.2", "graphql": "^16.6.0", "graphql-tag": "^2.12.6", "isbot": "^3.8.0", "react": "^18.2.0", "react-dom": "^18.2.0", "vitest": "^1.6.0" }, "devDependencies": { "@graphql-codegen/cli": "5.0.2", "@remix-run/dev": "^2.8.0", "@remix-run/eslint-config": "^2.8.0", "@shopify/hydrogen-codegen": "^0.3.1", "@shopify/mini-oxygen": "^3.0.2", "@shopify/oxygen-workers-types": "^4.0.0", "@shopify/prettier-config": "^1.1.2", "@total-typescript/ts-reset": "^0.4.2", "@types/eslint": "^8.4.10", "@types/react": "^18.2.22", "@types/react-dom": "^18.2.7", "eslint": "^8.20.0", "eslint-plugin-hydrogen": "0.12.2", "jsdom": "^24.1.0", "prettier": "^2.8.4", "typescript": "^5.2.2", "vite": "^5.1.0", "vite-tsconfig-paths": "^4.3.1" }, "engines": { "node": ">=18.0.0" } }
内容的提问来源于stack exchange,提问作者Jose Miguel Vega Lopez
相关产品推荐
相关产品推荐

