4

My component:

<script lang="ts">
  import { Button } from 'carbon-components-svelte';
  import firebase from 'firebase/app';
  import { auth } from '../../firebase-shortcut';
  import AuthButton from '../auth/AuthButton.svelte';

  let loggedIn: 'loading' | 'yes' | 'no' = 'loading';
  let userName: string;
  auth.onAuthStateChanged((x) => {
    loggedIn = Boolean(x) ? 'yes' : 'no';
    if (x) {
      userName = x.displayName;
    };
  })

  const googleProvider = {
    instance: new firebase.auth.GoogleAuthProvider(),
    name: 'Google'
  };
</script>

<section>
  <div>
    {#if loggedIn === 'yes'}
      <Button as let:props kind="secondary">
        <span {...props}>{userName}</span>
      </Button>
    {:else if loggedIn === 'no'}
      <AuthButton provider={googleProvider} />
    {:else}<!-- loggedIn === 'loading' -->
      <Button skeleton aria-busy="true" />
    {/if}
  </div>
</section>

test code:

import Toolbar from './Toolbar.svelte';
import { render, act } from '@testing-library/svelte';

jest.mock('../../firebase-shortcut');
const { __setAuthState } = require('../../firebase-shortcut');

describe('Toolbar', () => {
  it('should render loader', () => {
    const { queryByText } = render(Toolbar);

    const result = queryByText('로딩...');
    expect(result).toBeTruthy();
  });

  it('should render user when signed in', async () => {
    const displayName = '우섭';
    const { queryByText } = render(Toolbar);

    __setAuthState({ displayName });
    await act();

    const result = queryByText(displayName);
    expect(result).toBeTruthy();
  });

  it('should render button when not signed in', async () => {
    const { queryByRole } = render(Toolbar);

    __setAuthState(null);
    await act();

    const result = queryByRole('button');
    expect(result).toBeTruthy();
  });
});

mock file (__mocks__/firebase-shortcut.ts):

import type firebase from 'firebase/app';

const mocked = jest.createMockFromModule('./firebase-shortcut') as any;

let onAuthStateChanged: (x: Partial<firebase.User>) => void;
mocked.auth = {
  onAuthStateChanged: (f: (x: firebase.User) => void) => {
    onAuthStateChanged = f;
  },
};
mocked.__setAuthState = (x: Partial<firebase.User>) => {
  onAuthStateChanged && onAuthStateChanged(x);
};

module.exports = mocked;

Jest config at <project root>/jest.config.js:

module.exports = {
  preset: 'ts-jest',
  transform: {
    '^.+\\.svelte$': ['svelte-jester', { preprocess: true }],
    '^.+\\.ts$': 'ts-jest',
  },
  setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect'],
  moduleFileExtensions: ['js', 'ts', 'svelte']
};

If I print the component state by console.log(render(...).component), it prints that loggedIn state is correctly set as 'yes' and 'no' in each case. But the actual render result obtained by render(...).container.innerHTML, nothing's updated.

Plus the Jest output prints a weird error:

    TypeError: Cannot read property 'd' of undefined



      at Object.destroy [as d] (src/components/toolbar/Toolbar.svelte:296:40)
      at destroy_component (node_modules/svelte/internal/index.js:1434:36)
      at Toolbar.$destroy (node_modules/svelte/internal/index.js:1552:9)
      at Toolbar.$destroy (node_modules/svelte/internal/index.js:1665:15)
      at cleanupAtContainer (node_modules/@testing-library/svelte/dist/pure.js:116:48)
          at Array.forEach (<anonymous>)
      at cleanup (node_modules/@testing-library/svelte/dist/pure.js:126:37)
      at Object.<anonymous>.afterEach (node_modules/@testing-library/svelte/dist/index.js:27:23)

If I try "printing" loggedIn's value to HTML output, like

<section>
...
    {loggedIn}
    {#if loggedIn === 'yes'}
...

The output says loggedIn is 'yes' or 'no', but the if branches don't just seem to work.

Is there anything I'm doing wrong? Thanks in advance.

1 Answer 1

1

Using components from carbon-components-svelte seems to be the reason. I made them get injected via slots, so that during the test no Carbon components were actually rendered or even imported. Now tests are running okay.

Sign up to request clarification or add additional context in comments.

1 Comment

I have the same issue... When you said injected via slot what exactly it means? Could share the example? Thanks in advance

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.