mswjs / examples

Examples of Mock Service Worker usage with various frameworks and libraries.
683 stars 211 forks source link

mockup msw doesn't work #82

Closed santilp95 closed 1 year ago

santilp95 commented 1 year ago

Sorry for my bad english but this answer doesn't work my preview.js is this

const mockedQueryClient = new QueryClient();

addDecorator((Story) => (
  <QueryClientProvider client={mockedQueryClient}>
    <ThemeProvider theme={daviLabsTheme}>
      <ReactQueryDevtools />
      <Story />
    </ThemeProvider>
  </QueryClientProvider>
))

if (typeof global.process === 'undefined') {
  const { worker } = require("../mocks/server");
  worker.start();
}

but the console in firefox and chrome said

index.js:511 Uncaught (in promise) Error: [MSW] Failed to register a Service Worker for scope ('http://localhost:6006/') with script ('http://localhost:6006/mockServiceWorker.js'): Service Worker script does not exist at the given path.

Did you forget to run "npx msw init <PUBLIC_DIR>"?

Learn more about creating the Service Worker script: https://mswjs.io/docs/cli/init
    at getWorkerInstance (index.js:511:1)
    at async startWorkerInstance (index.js:1645:1)

I tried with Mock Service Worker and execute npx msw init public/but doesnt work , the react query is work when the api is ON, but I need to creaate and put the mock

Please help me to create correct mock

my handler.ts : I tried to create mock in two ways but doesnt wotk this same handler I put in storybook but doens't work

import { graphql, rest } from 'msw'
/**
 * a list of handlers (endpoints) to emulate (mock) a actual implementation
 */
export const handlers = [
    graphql.query('listBanksAch', (req, res, ctx) => {
        return res(
            ctx.data({
                tpAccounts: [
                    {
                        "id": 1,
                        "name": "Cuenta de ahorros"
                    },
                    {
                        "id": 2,
                        "name": "Cuenta Corriente"
                    },
                ]
            }),
        )
    }),
    rest.post("http://localhost:4005/graphql", (req, res, ctx) => {
        return res(
            ctx.status(200),
            ctx.json([
                {
                    "id": 1,
                    "name": "Cuenta de ahorros"
                },
                {
                    "id": 2,
                    "name": "Cuenta Corriente"
                },
            ])
        );
    })
]

My component is :

interface Props {
    /**
    * Open / close dialog
    */
    open: boolean;
    /**
     * Close dialog
     */
    onClose: () => void;
    /**
    * Function get form values
    */
    handleSubmit: (data: any) => void;
    /**
     * Init data to form
     */
    initData?: IFormACH;
}

export const DialogFormACH: FC<Props> = ({
    onClose,
    handleSubmit,
    open,
    initData,
}) => {

    const { banksACHData , typesAccountsACH} = useGetDataACH(open)

    const onSubmit = (data: any) => {
        handleSubmit(data);
        onClose();
    }
    return (
        <LayoutDialog
            open={open}
            onClose={onClose}
            fullWidth
            title={'ACH'}
            isLoading={banksACHData.isLoading || typesAccountsACH.isLoading}
        >
            <FormACH
                onSubmit={onSubmit}
                optionsBank={banksACHData.data!}
                optionsTypeCount={typesAccountsACH.data!}
                initData={initData}
            />
        </LayoutDialog>
    )
}

the hook is next:

const getTypesBankACH = async (): Promise<ListBanksAch[]> => {
    const query =
        `query  {
        listBanksAch {
            name
            nit
        }
    }`
    const { data: { data } } = await msListApi().post<IResponseBankACH>('/graphql', { query })

    return data.listBanksAch;
};

const geTypesAccounts = async (): Promise<TpAccount[]> => {
    const query =
        `query  {
        tpAccounts {
            id
            name
        }
    }`
    const { data: { data } } = await msListApi().post<ITypesAccountResponse>('/graphql', { query })

    return data.tpAccounts;
};

export const useGetDataACH = (open:boolean) => {
    const banksACHData = useQuery(['listBankACH',open],
        () => getTypesBankACH(),
        {
            enabled: open
        }
    )

    const typesAccountsACH = useQuery(['listAccountsACH',open],
        () => geTypesAccounts(),
        {
            enabled: open
        }
    )

    return {
        banksACHData,
        typesAccountsACH,
    }

and storybook is

export default {
    title: 'Molecules/Dialog/DialogFormACH',
    component: DialogFormACH,
    args: {
        handleSubmit: action('handleSubmit')
    },
    parameters: {
        layout: 'centered',

    },
} as ComponentMeta<typeof DialogFormACH>;

const Template: ComponentStory<typeof DialogFormACH> = (args) => {
    const [isOpen, setIsOpen] = useState(false);
    return (
        <>
            <Button onClick={() => setIsOpen(true)} variant='contained'>Open Dialog</Button>
            <DialogFormACH {...args} open={isOpen} onClose={() => setIsOpen(false)} />
        </>
    )
}

export const DialogFormACHExample = Template.bind({});
DialogFormACHExample.args = {};

Why mockServiceWorker not read in the browser and how put mock in storybook? , thanks

kettanaito commented 1 year ago

Hey! There are two things I recommend to solve this:

  1. Use msw-storybook-addon.
  2. Serve "public" since Storybook doesn't do that by default. I believe it's the "-p" flag in Storybook CLI.
santilp95 commented 1 year ago

thanks but the package.json have the flag "-p" "scripts": { "build": "next build", "build-storybook": "build-storybook", "chromatic": "npx chromatic --project-token=6110679b89b3", "dev": "next dev", "start": "next start", "export": "next export", "format": "prettier --write \"src/*/.{js,jsx,ts,tsx}\"", "lint": "eslint --fix \"src/*/.{js,jsx,ts,tsx}\"", "storybook": "start-storybook -p 6006", "test": "jest --watch", "test:ci": "jest --ci" },

kettanaito commented 1 year ago

My bad, then it's -s, stands for "static". -s ./public is what you need.