import { jsx, jsxs, Fragment } from 'solid-jsx/jsx-runtime';

/*@jsxRuntime automatic @jsxImportSource solid-jsx*/
const toc = [{
  "depth": 1,
  "value": "Solid 테스트",
  "children": [{
    "depth": 2,
    "value": "테스트 설정",
    "children": [{
      "depth": 3,
      "value": "Jest 설정",
      "children": [{
        "depth": 4,
        "value": "solid-jest 사용하기",
        "children": []
      }, {
        "depth": 4,
        "value": "ts-jest 사용하기",
        "children": []
      }]
    }, {
      "depth": 3,
      "value": "타입스크립트와 Jest",
      "children": []
    }, {
      "depth": 3,
      "value": "uvu 설정하기",
      "children": []
    }, {
      "depth": 3,
      "value": "커버리지 리포트",
      "children": []
    }, {
      "depth": 3,
      "value": "워치 모드",
      "children": []
    }, {
      "depth": 3,
      "value": "solid-testing-library",
      "children": []
    }, {
      "depth": 3,
      "value": "@testing-library/jest-dom",
      "children": []
    }, {
      "depth": 3,
      "value": "solid-dom-testing",
      "children": []
    }]
  }, {
    "depth": 2,
    "value": "vitest",
    "children": []
  }, {
    "depth": 2,
    "value": "테스트 패턴 및 베스트 프랙티스",
    "children": [{
      "depth": 3,
      "value": "리액티브 상태 테스트",
      "children": [{
        "depth": 4,
        "value": "Jest / vitest 테스트",
        "children": []
      }, {
        "depth": 4,
        "value": "uvu 테스트",
        "children": []
      }]
    }, {
      "depth": 3,
      "value": "테스트 디렉티브",
      "children": [{
        "depth": 4,
        "value": "Jest / vitest 테스트",
        "children": []
      }, {
        "depth": 4,
        "value": "uvu 테스트",
        "children": []
      }]
    }, {
      "depth": 3,
      "value": "컴포넌트 테스트",
      "children": [{
        "depth": 4,
        "value": "Jest / vitest 테스트",
        "children": []
      }, {
        "depth": 4,
        "value": "uvu 테스트",
        "children": []
      }]
    }]
  }]
}];
function _createMdxContent(props) {
  const _components = Object.assign({
    h1: "h1",
    a: "a",
    p: "p",
    h2: "h2",
    h3: "h3",
    h4: "h4",
    pre: "pre",
    code: "code",
    span: "span",
    blockquote: "blockquote",
    ol: "ol",
    li: "li"
  }, props.components);
  return jsxs(Fragment, {
    children: [jsxs(_components.h1, {
      id: "solid-테스트",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#solid-테스트",
        children: "#"
      }), "Solid 테스트"]
    }), "\n", jsx(_components.p, {
      children: "프로덕션에서 Solid 코드를 사용하려면 테스트가 필요합니다. 모든 테스트를 수동으로 하고 싶지는 않을테니, 자동화된 테스트가 필요합니다. 이 가이드에는 모든 설정 방법과 함께 Solid 코드 테스트를 위한 몇 가지 유용한 테스트 패턴에 대해 설명합니다."
    }), "\n", jsxs(_components.h2, {
      id: "테스트-설정",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#테스트-설정",
        children: "#"
      }), "테스트 설정"]
    }), "\n", jsx(_components.p, {
      children: "테스트 환경을 설정하기 전에, 테스트 Runner를 먼저 선택해야 합니다. 많은 선택지가 있지만, 매우 극단적으로 반대되는 두 개의 프로젝트인 uvu와 Jest, 그리고 vitest라는 새로운 선택지에 촛점을 맞출 것입니다. Jest 는 강력하게 통합되어 있으며, uvu는 필수적인 기능만 제공하고, vitest는 모든 기능을 갖추고 있지만 단순합니다. 다른 테스트 Runner를 사용하고 싶다면, uvu 설정 방법을 적용하면 다른 대부분의 테스트 Runner에서도 작동할 것입니다."
    }), "\n", jsxs(_components.h3, {
      id: "jest-설정",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#jest-설정",
        children: "#"
      }), "Jest 설정"]
    }), "\n", jsx(_components.p, {
      children: "안타깝게도, 통합이 되더라도, jest는 esm 이나 타입스크립트를 바로 지원하지 않으며, 변환을 위한 설정이 필요합니다."
    }), "\n", jsx(_components.p, {
      children: "첫번째 옵션은 babel을 사용해 Solid 코드를 변환하고 타입스크립트 사용시 타입 체크를 제거하는 solid-jest 입니다. 다른 옵션은 타입스크립트 컴파일러를 사용해 테스트내에서 타입을 체크하는 ts-jest입니다."
    }), "\n", jsx(_components.p, {
      children: "타입스크립트를 사용하지 않는다면 solid-jest를 사용하고, 테스트 실행시 타입을 체크하려면 ts-jest를 선택하세요."
    }), "\n", jsxs(_components.h4, {
      id: "solid-jest-사용하기",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#solid-jest-사용하기",
        children: "#"
      }), "solid-jest 사용하기"]
    }), "\n", jsx(_components.p, {
      children: "필요한 디펜던시를 설치합니다:"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-sh",
        children: ["> npm i --save-dev jest solid-jest ", jsx(_components.span, {
          className: "hljs-comment",
          children: "# yarn add -D 또는 pnpm"
        }), "\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "타입스크립트 사용시:"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-sh",
        children: ["> npm i --save-dev jest solid-jest @types/jest ", jsx(_components.span, {
          className: "hljs-comment",
          children: "# yarn add -D 또는 pnpm"
        }), "\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["다음으로, ", jsx(_components.code, {
        children: ".babelrc"
      }), "가 설정되어 있지 않다면 다음과 같이 정의해야합니다:"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-js",
        children: ["{\n  ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"presets\""
        }), ": [\n    ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"@babel/preset-env\""
        }), ",\n    ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"babel-preset-solid\""
        }), ",\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// solid-jest와 타입스크립트 사용시"
        }), "\n    ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"@babel/preset-typescript\""
        }), "\n  ]\n}\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.code, {
        children: "package.json"
      }), "를 아래와 같이 수정합니다:"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-js",
        children: ["{\n  ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"scripts\""
        }), ": {\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// ..."
        }), "\n    ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"test\""
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"jest\""
        }), "\n  },\n  ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"jest\""
        }), ": {\n    ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"preset\""
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-jest/preset/browser\""
        }), ",\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// ..."
        }), "\n  }\n}\n"]
      })
    }), "\n", jsxs(_components.h4, {
      id: "ts-jest-사용하기",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#ts-jest-사용하기",
        children: "#"
      }), "ts-jest 사용하기"]
    }), "\n", jsx(_components.p, {
      children: "ts-jest를 사용하려면, 먼저 설치가 필요합니다:"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-sh",
        children: ["> npm i --save-dev jest ts-jest @types/jest ", jsx(_components.span, {
          className: "hljs-comment",
          children: "# yarn add -D 또는 pnpm"
        }), "\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.code, {
        children: "package.json"
      }), " 파일에서 다음과 같이 설정합니다:"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-js",
        children: ["{ \n  ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"scripts\""
        }), ": {\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// ..."
        }), "\n    ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"test\""
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"jest\""
        }), "\n  },\n  ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"jest\""
        }), ": {\n    ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"preset\""
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"ts-jest\""
        }), ",\n    ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"globals\""
        }), ": {\n      ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"ts-jest\""
        }), ": {\n        ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"tsconfig\""
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"tsconfig.json\""
        }), ",\n        ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"babelConfig\""
        }), ": {\n          ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"presets\""
        }), ": [\n            ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"babel-preset-solid\""
        }), ",\n            ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"@babel/preset-env\""
        }), "\n          ]\n        }\n      }\n    },\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// ..."
        }), "\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 브라우저 모드에서 테스트:"
        }), "\n    ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"testEnvironment\""
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"jsdom\""
        }), ",\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 불행히도 solid는 브라우저 모드를 감지하지 못하기 때문에, 직접 사용할 버전을 지정해야합니다:"
        }), "\n    ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"moduleNameMapper\""
        }), ": {\n      ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js/web\""
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"<rootDir>/node_modules/solid-js/web/dist/web.cjs\""
        }), ",\n      ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js\""
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"<rootDir>/node_modules/solid-js/dist/solid.cjs\""
        }), "\n    }\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 윈도우 사용자는 \"/\"를 \"\\\"로 변경해야합니다."
        }), "\n  }\n}\n"]
      })
    }), "\n", jsxs(_components.h3, {
      id: "타입스크립트와-jest",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#타입스크립트와-jest",
        children: "#"
      }), "타입스크립트와 Jest"]
    }), "\n", jsx(_components.p, {
      children: "jest는 테스트 기능을 전역 스코프에 주입하기 때문에, 타입스크립트 사용시 jest 타입을 tsconfig.json 파일에 로드해야 합니다:"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-js",
        children: ["{\n  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// ..."
        }), "\n  ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"types\""
        }), ": [", jsx(_components.span, {
          className: "hljs-string",
          children: "\"jest\""
        }), "]\n}\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["이 설정을 위해서는 앞에서 설명한대로 ", jsx(_components.code, {
        children: "@types/jest"
      }), "를 설치되어 있어야 합니다."]
    }), "\n", jsxs(_components.h3, {
      id: "uvu-설정하기",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#uvu-설정하기",
        children: "#"
      }), "uvu 설정하기"]
    }), "\n", jsx(_components.p, {
      children: "먼저 필요한 패키지를 설치해야 합니다:"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-sh",
        children: ["> npm i --save-dev uvu solid-register jsdom ", jsx(_components.span, {
          className: "hljs-comment",
          children: "# yarn add -D 또는 pnpm"
        }), "\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.code, {
        children: "package.json"
      }), " 파일에 테스트 스크립트를 설정합니다:"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-sh",
        children: ["> npm set-script ", jsx(_components.span, {
          className: "hljs-built_in",
          children: "test"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"uvu -r solid-register\""
        }), "\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["추가 설정 파일은 ", jsx(_components.code, {
        children: "-r setup.ts"
      }), "을 사용해 추가하며, 테스트 제외 파일들은 ", jsx(_components.code, {
        children: "-i not-a-test.test.ts"
      }), "를 사용합니다."]
    }), "\n", jsxs(_components.h3, {
      id: "커버리지-리포트",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#커버리지-리포트",
        children: "#"
      }), "커버리지 리포트"]
    }), "\n", jsxs(_components.blockquote, {
      children: ["\n", jsxs(_components.p, {
        children: ["안타깝게도 ", jsx(_components.a, {
          href: "https://github.com/babel/babel/issues/4289",
          children: "babel의 한계"
        }), "로 인해 트랜스파일된 JSX 파일에 대해 소스맵을 얻을 수 없으며, 이로 인해 컴포넌트 커버리지가 0이 되는 문제가 있습니다. 하지만 JSX가 아닌 코드에 대해서는 정상 작동합니다."]
      }), "\n"]
    }), "\n", jsx(_components.p, {
      children: "테스트 코드 커버리지를 확인하려 할 떄, uvu에서 선호하는 도구는 c8 입니다. 설치 후 설정을 위해서는 다음과 같이 실행합니다:"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-sh",
        children: ["> npm i --save-dev c8 ", jsx(_components.span, {
          className: "hljs-comment",
          children: "# yarn add -D 또는 pnpm"
        }), "\n> npm set-script ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"test:coverage\""
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"c8 uvu -r solid-register\""
        }), "\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["이제 ", jsx(_components.code, {
        children: "npm run test:coverage"
      }), "를 실행하면, 테스트 커버리지를 확인할 수 있습니다."]
    }), "\n", jsxs(_components.p, {
      children: ["멋진 HTML 커버리지 리포트를 원하신다면, ", jsx(_components.code, {
        children: "c8"
      }), " 대신 ", jsx(_components.code, {
        children: "c8 -r html"
      }), "을 사용해 HTML 리포터를 활성화할 수 있습니다."]
    }), "\n", jsxs(_components.h3, {
      id: "워치-모드",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#워치-모드",
        children: "#"
      }), "워치 모드"]
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.code, {
        children: "uvu"
      }), " 나 ", jsx(_components.code, {
        children: "tape"
      }), " 는 워치 모드를 지원하지 않지만, ", jsx(_components.code, {
        children: "chokidar-cli"
      }), " 를 사용해 워치 모드로 실행할 수 있습니다:"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-sh",
        children: ["> npm i --save-dev chokidar-cli ", jsx(_components.span, {
          className: "hljs-comment",
          children: "# yarn add -D 또는 pnpm"
        }), "\n> npm set-script ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"test:watch\""
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"chokidar src/**/*.ts src/**/*.tsx -c \\\"uvu -r solid-register\\\"\n# use .js/.jsx instead of .ts/.tsx\n"
        })]
      })
    }), "\n", jsxs(_components.p, {
      children: ["이제 ", jsx(_components.code, {
        children: "npm run test:watch"
      }), "를 실행하면, 파일이 변경시마다 테스트를 실행하게 됩니다."]
    }), "\n", jsxs(_components.h3, {
      id: "solid-testing-library",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#solid-testing-library",
        children: "#"
      }), "solid-testing-library"]
    }), "\n", jsxs(_components.p, {
      children: ["컴포넌트 테스트를 위해서는 ", jsx(_components.code, {
        children: "solid-testing-library"
      }), "를 설치합니다:"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-sh",
        children: ["> npm i --save-dev solid-testing-library ", jsx(_components.span, {
          className: "hljs-comment",
          children: "# yarn add -D 또는 pnpm"
        }), "\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "이 라이브러리를 사용하면 컴포넌트를 렌더링하고, 사용자 입장에서 이벤트를 발생하고 엘리먼트를 선택할 수 있습니다."
    }), "\n", jsxs(_components.h3, {
      id: "testing-libraryjest-dom",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#testing-libraryjest-dom",
        children: "#"
      }), "@testing-library/jest-dom"]
    }), "\n", jsxs(_components.p, {
      children: ["jest를 사용중이라면, ", jsx(_components.code, {
        children: "solid-testing-library"
      }), " 는 ", jsx(_components.code, {
        children: "@testing-library/jest-dom"
      }), "와 잘 작동합니다:"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-sh",
        children: ["> npm i --save-dev @testing-library/jest-dom ", jsx(_components.span, {
          className: "hljs-comment",
          children: "# yarn add -D 또는 pnpm"
        }), "\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "jest 셋업 파일에서 익스텐션을 임포트합니다:"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-comment",
          children: "// test/jest-setup.ts"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "'@testing-library/jest-dom/extend-expect'"
        }), ";\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.code, {
        children: "package.json"
      }), " 파일에서 다음과 같이 익스텐션을 로드합니다:"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-js",
        children: ["{\n  ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"jest\""
        }), ": {\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// ..."
        }), "\n    ", jsx(_components.span, {
          className: "hljs-attr",
          children: "setupFiles"
        }), ": [", jsx(_components.span, {
          className: "hljs-string",
          children: "\"@testing-library/jest-dom/extend-expect\""
        }), ", ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"regenerator-runtime\""
        }), "]\n  }\n}\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.code, {
        children: "tsconfig.json"
      }), " 파일에도 다음과 같이 추가합니다:"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-js",
        children: ["{\n  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// ..."
        }), "\n  ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"types\""
        }), ": [", jsx(_components.span, {
          className: "hljs-string",
          children: "\"jest\""
        }), ", ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"@testing-library/jest-dom\""
        }), "]\n}\n"]
      })
    }), "\n", jsxs(_components.h3, {
      id: "solid-dom-testing",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#solid-dom-testing",
        children: "#"
      }), "solid-dom-testing"]
    }), "\n", jsxs(_components.p, {
      children: ["uvu 혹은 tape 와 같은 테스트 Runner를 사용하는 경우, ", jsx(_components.code, {
        children: "solid-dom-testing"
      }), " 와 같은 어설션을 도와주는 라이브러리가 있습니다:"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-sh",
        children: ["> npm i --save-dev solid-dom-testing ", jsx(_components.span, {
          className: "hljs-comment",
          children: "# yarn add -D 또는 pnpm"
        }), "\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "추가 설정은 필요없으며, 테스트 파일에서 필요한 헬퍼를 임포트해 사용하면 됩니다."
    }), "\n", jsxs(_components.h2, {
      id: "vitest",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#vitest",
        children: "#"
      }), "vitest"]
    }), "\n", jsxs(_components.p, {
      children: ["유닛 테스트 관련해 ", jsx(_components.a, {
        href: "https://vitest.dev/",
        children: "vitest"
      }), "라는 도구가 새로 나왔습니다.\nvitest는 jest와 동일한 기능들을 제공하면서 보다 빠른 속도를 제공해 jest를 대체하는 것을 목표로 합니다."]
    }), "\n", jsx(_components.p, {
      children: "설치는 간단합니다:"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-sh",
        children: ["> npm i --save-dev vitest jsdom ", jsx(_components.span, {
          className: "hljs-comment",
          children: "# or yarn add -D 또는 pnpm"
        }), "\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["공식 starter 혹은 solid-start를 사용 중이라면, 이미 vite를 사용중이기 때문에", jsx(_components.code, {
        children: "vite.config.mjs"
      }), " 파일이 있을 것입니다. 파일을 다음과 같이 수정하세요:"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-js",
        children: [jsx(_components.span, {
          className: "hljs-comment",
          children: "/// <reference types=\"vitest\" />"
        }), "\n", jsx(_components.span, {
          className: "hljs-comment",
          children: "/// <reference types=\"vite/client\" />"
        }), "\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { defineConfig } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "'vite'"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " solid ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "'solid-start'"
        }), " ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 또는 'vite-plugin-solid'"
        }), "\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "export"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "default"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "defineConfig"
        }), "({\n  ", jsx(_components.span, {
          className: "hljs-attr",
          children: "test"
        }), ": {\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// `describe, test, it`를 전역으로 사용하고 싶다면 아래의 주석을 해제하세요:"
        }), "\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// globals: true,"
        }), "\n    ", jsx(_components.span, {
          className: "hljs-attr",
          children: "environment"
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "'jsdom'"
        }), ",\n    ", jsx(_components.span, {
          className: "hljs-attr",
          children: "transformMode"
        }), ": {\n      ", jsx(_components.span, {
          className: "hljs-attr",
          children: "web"
        }), ": [", jsx(_components.span, {
          className: "hljs-regexp",
          children: "/\\.[jt]sx$/"
        }), "],\n    },\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// vitest에서의 모듈 검색 이슈를 해결하려면 solid를 인라인으로 설정해야 합니다."
        }), "\n    ", jsx(_components.span, {
          className: "hljs-attr",
          children: "deps"
        }), ": {\n      ", jsx(_components.span, {
          className: "hljs-attr",
          children: "inline"
        }), ": [", jsx(_components.span, {
          className: "hljs-regexp",
          children: "/solid-js/"
        }), "],\n    },\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 테스트가 별로 없다면, 퍼포먼스 향상을 위해 아래 주석을 하나 혹은 둘 다 해제하세요:"
        }), "\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// threads: false,"
        }), "\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// isolate: false,"
        }), "\n  },\n  ", jsx(_components.span, {
          className: "hljs-attr",
          children: "plugins"
        }), ": [", jsx(_components.span, {
          className: "hljs-title function_",
          children: "solid"
        }), "()],\n  ", jsx(_components.span, {
          className: "hljs-attr",
          children: "resolve"
        }), ": {\n    ", jsx(_components.span, {
          className: "hljs-attr",
          children: "conditions"
        }), ": [", jsx(_components.span, {
          className: "hljs-string",
          children: "'development'"
        }), ", ", jsx(_components.span, {
          className: "hljs-string",
          children: "'browser'"
        }), "],\n  },\n})\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["마지막으로 ", jsx(_components.code, {
        children: "package.json"
      }), " 파일에 test 스크립트를 추가하세요:"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-sh",
        children: ["> npm set-script ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"test\""
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"vitest\""
        }), "\n"]
      })
    }), "\n", jsxs(_components.h2, {
      id: "테스트-패턴-및-베스트-프랙티스",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#테스트-패턴-및-베스트-프랙티스",
        children: "#"
      }), "테스트 패턴 및 베스트 프랙티스"]
    }), "\n", jsx(_components.p, {
      children: "테스트 도구를 설치했으니, 이제 사용할 차례입니다. 사용 편의를 위해 solid는 몇 가지 패턴을 지원합니다."
    }), "\n", jsxs(_components.h3, {
      id: "리액티브-상태-테스트",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#리액티브-상태-테스트",
        children: "#"
      }), "리액티브 상태 테스트"]
    }), "\n", jsxs(_components.p, {
      children: ["유지 보수를 쉽게 하거나 여러 개의 뷰를 지원하기 위해 컴포넌트와 상태를 분리해 유지할 수 있습니다. 이 경우 테스트하는 인터페이스는 상태 그 자체입니다.\n", jsx(_components.a, {
        href: "https://www.solidjs.com/docs/latest/api#createroot",
        children: "리액티브 루트"
      }), "에서 벗어나면 상태가 추적되지 않으며, 업데이트가 되더라도 이펙트와 메모가 트리거되지 않습니다."]
    }), "\n", jsxs(_components.p, {
      children: ["또한, 이펙트는 비동기로 트리거되기 때문에, 최종 이펙트에서 어설션을 래핑하는 것이 도움이 됩니다.\n또는, 여러 변경 사항에 걸친 일련의 이펙트를 관찰하려면, ", jsx(_components.code, {
        children: "createRoot"
      }), "에서 필요한 도구를 반환하고, 비동기 테스트 함수에서 이를 실행하는 것이 도움이 될 수 있습니다. (이는 ", jsx(_components.code, {
        children: "createRoot"
      }), " 자체는 비동기 함수를 받을 수 없기 때문입니다)."]
    }), "\n", jsxs(_components.p, {
      children: ["예를 들어, ", jsx(_components.a, {
        href: "https://www.solidjs.com/examples/todos",
        children: "todo 예제"
      }), "에서 ", jsx(_components.code, {
        children: "createLocalStorage"
      }), " 를 테스트 하려면:"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { createEffect } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js\""
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { createStore, ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Store"
        }), ", ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "SetStoreFunction"
        }), " } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js/store\""
        }), ";\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "export"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "function"
        }), " createLocalStore<T>(", jsx(_components.span, {
          className: "hljs-attr",
          children: "initState"
        }), ": T): [", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Store"
        }), "<T>, ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "SetStoreFunction"
        }), "<T>] {\n\t", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [state, setState] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createStore"
        }), "(initState);\n\t", jsx(_components.span, {
          className: "hljs-keyword",
          children: "if"
        }), " (", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "localStorage"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "todos"
        }), ") ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "setState"
        }), "(", jsx(_components.span, {
          className: "hljs-title class_",
          children: "JSON"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "parse"
        }), "(", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "localStorage"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "todos"
        }), "));\n\t", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createEffect"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " (", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "localStorage"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "todos"
        }), " = ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "JSON"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "stringify"
        }), "(state)));\n\t", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " [state, setState];\n}\n"]
      })
    }), "\n", jsx(_components.p, {
      children: "TODO 컴포넌트를 생성하는 대신, 이 모델을 독립적으로 테스트할 수 있습니다. 이 경우 다음과 같은 점을 명심해야 합니다."
    }), "\n", jsxs(_components.ol, {
      children: ["\n", jsxs(_components.li, {
        children: ["리액티브 변경 사항은 ", jsx(_components.code, {
          children: "render"
        }), " 혹은 ", jsx(_components.code, {
          children: "createRoot"
        }), "에서 제공하는 추적 컨텍스트가 있는 경우에만 동작하며,"]
      }), "\n", jsxs(_components.li, {
        children: ["리액티브 변경 사항은 비동기이지만, 이를 캐치하려면 ", jsx(_components.code, {
          children: "createEffect"
        }), "를 사용해야 합니다.\n", jsx(_components.code, {
          children: "createRoot"
        }), "를 사용하면 수동 해제를 트리거할 수 있다는 장점이 있습니다."]
      }), "\n"]
    }), "\n", jsxs(_components.h4, {
      id: "jest--vitest-테스트",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#jest--vitest-테스트",
        children: "#"
      }), "Jest / vitest 테스트"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { createLocalStore } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"./main.tsx\""
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { createRoot, createEffect } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js\""
        }), ";\n\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "describe"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"createLocalStore\""
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "beforeEach"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " { \n    ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "localStorage"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "removeItem"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"todos\""
        }), ");\n  });\n\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " initialState = {\n    ", jsx(_components.span, {
          className: "hljs-attr",
          children: "todos"
        }), ": [],\n    ", jsx(_components.span, {
          className: "hljs-attr",
          children: "newTitle"
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"\""
        }), "\n  };\n\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "test"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"it reads pre-existing state from localStorage\""
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createRoot"
        }), "(", jsxs(_components.span, {
          className: "hljs-function",
          children: [jsx(_components.span, {
            className: "hljs-params",
            children: "dispose"
          }), " =>"]
        }), " {\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " savedState = { ", jsx(_components.span, {
          className: "hljs-attr",
          children: "todos"
        }), ": [], ", jsx(_components.span, {
          className: "hljs-attr",
          children: "newTitle"
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"saved\""
        }), " };\n    ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "localStorage"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "setItem"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"todos\""
        }), ", ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "JSON"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "stringify"
        }), "(savedState));\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [state] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createLocalStore"
        }), "(initialState);\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "expect"
        }), "(state).", jsx(_components.span, {
          className: "hljs-title function_",
          children: "toEqual"
        }), "(savedState);\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "dispose"
        }), "();\n  }));\n\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "test"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"it stores new state to localStorage\""
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createRoot"
        }), "(", jsxs(_components.span, {
          className: "hljs-function",
          children: [jsx(_components.span, {
            className: "hljs-params",
            children: "dispose"
          }), " =>"]
        }), " {\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [state, setState] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createLocalStore"
        }), "(initialState);\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "setState"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"newTitle\""
        }), ", ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"updated\""
        }), ");\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 이펙트를 캐치하려면, 이펙트를 사용합니다."
        }), "\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "new"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Promise"
        }), "<", jsx(_components.span, {
          className: "hljs-built_in",
          children: "void"
        }), ">(", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "resolve"
          }), ") =>"]
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createEffect"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n      ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "expect"
        }), "(", jsx(_components.span, {
          className: "hljs-title class_",
          children: "JSON"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "parse"
        }), "(", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "localStorage"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "todos"
        }), " || ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"\""
        }), "))\n        .", jsx(_components.span, {
          className: "hljs-title function_",
          children: "toEqual"
        }), "({ ", jsx(_components.span, {
          className: "hljs-attr",
          children: "todos"
        }), ": [], ", jsx(_components.span, {
          className: "hljs-attr",
          children: "newTitle"
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"updated\""
        }), " });\n      ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "dispose"
        }), "();\n      ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "resolve"
        }), "();\n    }));\n  }));\n\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "test"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"it updates state multiple times\""
        }), ", ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "async"
        }), " () => {\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " {dispose, setState} = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createRoot"
        }), "(", jsxs(_components.span, {
          className: "hljs-function",
          children: [jsx(_components.span, {
            className: "hljs-params",
            children: "dispose"
          }), " =>"]
        }), " {\n      ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [state, setState] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createLocalStore"
        }), "(initialState);\n      ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " {dispose, setState};\n    });\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "setState"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"newTitle\""
        }), ", ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"first\""
        }), ");\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// wait a tick to resolve all effects"
        }), "\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "await"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "new"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Promise"
        }), "(", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "done"
          }), ") =>"]
        }), " ", jsx(_components.span, {
          className: "hljs-built_in",
          children: "setTimeout"
        }), "(done, ", jsx(_components.span, {
          className: "hljs-number",
          children: "0"
        }), "));\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "expect"
        }), "(", jsx(_components.span, {
          className: "hljs-title class_",
          children: "JSON"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "parse"
        }), "(", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "localStorage"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "todos"
        }), " || ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"\""
        }), "))\n      .", jsx(_components.span, {
          className: "hljs-title function_",
          children: "toEqual"
        }), "({ ", jsx(_components.span, {
          className: "hljs-attr",
          children: "todos"
        }), ": [], ", jsx(_components.span, {
          className: "hljs-attr",
          children: "newTitle"
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"first\""
        }), " });\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "setState"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"newTitle\""
        }), ", ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"second\""
        }), ");\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "await"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "new"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Promise"
        }), "(", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "done"
          }), ") =>"]
        }), " ", jsx(_components.span, {
          className: "hljs-built_in",
          children: "setTimeout"
        }), "(done, ", jsx(_components.span, {
          className: "hljs-number",
          children: "0"
        }), "));\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "expect"
        }), "(", jsx(_components.span, {
          className: "hljs-title class_",
          children: "JSON"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "parse"
        }), "(", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "localStorage"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "todos"
        }), " || ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"\""
        }), "))\n      .", jsx(_components.span, {
          className: "hljs-title function_",
          children: "toEqual"
        }), "({ ", jsx(_components.span, {
          className: "hljs-attr",
          children: "todos"
        }), ": [], ", jsx(_components.span, {
          className: "hljs-attr",
          children: "newTitle"
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"first\""
        }), " });\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "dispose"
        }), "();\n  });\n});\n"]
      })
    }), "\n", jsxs(_components.h4, {
      id: "uvu-테스트",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#uvu-테스트",
        children: "#"
      }), "uvu 테스트"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { createLocalStore } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"./main\""
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { suite } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"uvu\""
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " * ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "as"
        }), " assert ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"uvu/assert\""
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { createEffect, createRoot } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js\""
        }), ";\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " todoTest = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "suite"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"createLocalStore\""
        }), ");\n\ntodoTest.", jsx(_components.span, {
          className: "hljs-property",
          children: "before"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "each"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " { \n  ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "localStorage"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "removeItem"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"todos\""
        }), ");\n});\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " initialState = {\n  ", jsx(_components.span, {
          className: "hljs-attr",
          children: "todos"
        }), ": [],\n  ", jsx(_components.span, {
          className: "hljs-attr",
          children: "newTitle"
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"\""
        }), "\n};\n\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "todoTest"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"it reads pre-existing state from localStorage\""
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " \n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createRoot"
        }), "(", jsxs(_components.span, {
          className: "hljs-function",
          children: [jsx(_components.span, {
            className: "hljs-params",
            children: "dispose"
          }), " =>"]
        }), " {\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " savedState = { ", jsx(_components.span, {
          className: "hljs-attr",
          children: "todos"
        }), ": [], ", jsx(_components.span, {
          className: "hljs-attr",
          children: "newTitle"
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"saved\""
        }), " };\n    ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "localStorage"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "setItem"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"todos\""
        }), ", ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "JSON"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "stringify"
        }), "(savedState));\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [state] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createLocalStore"
        }), "(initialState);\n    assert.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "equal"
        }), "(state, savedState);\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "dispose"
        }), "();\n  }));\n\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "todoTest"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"it stores new state to localStorage\""
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), "\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createRoot"
        }), "(", jsxs(_components.span, {
          className: "hljs-function",
          children: [jsx(_components.span, {
            className: "hljs-params",
            children: "dispose"
          }), " =>"]
        }), " {\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [_, setState] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createLocalStore"
        }), "(initialState);\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "setState"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"newTitle\""
        }), ", ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"updated\""
        }), ");\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// 이펙트를 캐치하려면, 이펙트를 사용합니다."
        }), "\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "new"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Promise"
        }), "<", jsx(_components.span, {
          className: "hljs-built_in",
          children: "void"
        }), ">(", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "resolve"
          }), ") =>"]
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createEffect"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n      assert.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "equal"
        }), "(\n        ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "JSON"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "parse"
        }), "(", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "localStorage"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "todos"
        }), " || ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"\""
        }), "),\n        { ", jsx(_components.span, {
          className: "hljs-attr",
          children: "todos"
        }), ": [], ", jsx(_components.span, {
          className: "hljs-attr",
          children: "newTitle"
        }), ": ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"updated\""
        }), " }\n      );\n      ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "dispose"
        }), "();\n      ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "resolve"
        }), "();\n    }));\n  }));\n\ntodoTest.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "run"
        }), "();\n"]
      })
    }), "\n", jsxs(_components.h3, {
      id: "테스트-디렉티브",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#테스트-디렉티브",
        children: "#"
      }), "테스트 디렉티브"]
    }), "\n", jsxs(_components.p, {
      children: [jsx(_components.a, {
        href: "https://www.solidjs.com/docs/latest/api#use%3A___",
        children: "디렉티브"
      }), "를 사용하면 ref 를 재사용 가능한 방식으로 사용할 수 있습니다. 이는 기본적으로 ", jsx(_components.code, {
        children: "(ref: HTMLElement, data: Accessor<any>) => void"
      }), " 형식의 함수입니다. ", jsx(_components.a, {
        href: "https://www.solidjs.com/tutorial/bindings_directives?solved",
        children: "디렉티브 튜토리얼"
      }), "에서는, 접근자 인자에 래핑된 콜백을 호출하는 ", jsx(_components.code, {
        children: "clickOutside"
      }), " 디렉티브를 정의합니다."]
    }), "\n", jsx(_components.p, {
      children: "이제 컴포넌트를 만들고, 디렉티브를 사용할 수 있지만, 디렉티브를 직접 테스트하는 대신 디렉티브를 사용하는 것을 테스트합니다. 마운트된 노드와 접근자를 제공해서 디렉티브의 외부를 테스트하는 것이 더 간단합니다."
    }), "\n", jsxs(_components.h4, {
      id: "jest--vitest-테스트-1",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#jest--vitest-테스트-1",
        children: "#"
      }), "Jest / vitest 테스트"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-comment",
          children: "// click-outside.test.ts"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " clickOutside ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"click-outside\""
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { createRoot } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js\""
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { fireEvent } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-testing-library\""
        }), ";\n\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "describe"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"clickOutside\""
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ref = ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "document"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createElement"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"div\""
        }), ");\n  \n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "beforeAll"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n    ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "document"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "body"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "appendChild"
        }), "(ref);\n  });\n\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "afterAll"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n    ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "document"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "body"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "removeChild"
        }), "(ref);\n  });\n\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "test"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"will trigger on click outside\""
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createRoot"
        }), "(", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "dispose"
          }), ") =>"]
        }), "\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "new"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Promise"
        }), "<", jsx(_components.span, {
          className: "hljs-built_in",
          children: "void"
        }), ">(", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "resolve"
          }), ") =>"]
        }), " {\n      ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "let"
        }), " clickedOutside = ", jsx(_components.span, {
          className: "hljs-literal",
          children: "false"
        }), ";\n      ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "clickOutside"
        }), "(ref, ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " { clickedOutside = ", jsx(_components.span, {
          className: "hljs-literal",
          children: "true"
        }), "; });\n      ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "document"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "body"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "addEventListener"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"click\""
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n        ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "expect"
        }), "(clickedOutside).", jsx(_components.span, {
          className: "hljs-title function_",
          children: "toBeTruthy"
        }), "();\n        ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "dispose"
        }), "();\n        ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "resolve"
        }), "();\n      });\n      fireEvent.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "click"
        }), "(", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "document"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "body"
        }), ");\n    })\n  ));\n\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "test"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"will not trigger on click inside\""
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createRoot"
        }), "(", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "dispose"
          }), ") =>"]
        }), "\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "new"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Promise"
        }), "<", jsx(_components.span, {
          className: "hljs-built_in",
          children: "void"
        }), ">(", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "resolve"
          }), ") =>"]
        }), " {\n      ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "let"
        }), " clickedOutside = ", jsx(_components.span, {
          className: "hljs-literal",
          children: "false"
        }), ";\n      ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "clickOutside"
        }), "(ref, ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " { clickedOutside = ", jsx(_components.span, {
          className: "hljs-literal",
          children: "true"
        }), "; });\n      ref.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "addEventListener"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"click\""
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n        ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "expect"
        }), "(clickedOutside).", jsx(_components.span, {
          className: "hljs-title function_",
          children: "toBeFalsy"
        }), "();\n        ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "dispose"
        }), "();\n        ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "resolve"
        }), "();\n      });\n      fireEvent.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "click"
        }), "(ref);\n    })\n  ));\n});\n"]
      })
    }), "\n", jsxs(_components.h4, {
      id: "uvu-테스트-1",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#uvu-테스트-1",
        children: "#"
      }), "uvu 테스트"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-comment",
          children: "// click-outside.test.ts"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " clickOutside ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "'click-outside.tsx'"
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { createRoot } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "'solid-js'"
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { fireEvent } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "'solid-testing-library'"
        }), ";\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " clickTest = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "suite"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "'clickOutside'"
        }), ");\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ref = ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "document"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createElement"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "'div'"
        }), ");\n  \nclickTest.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "before"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "document"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "body"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "appendChild"
        }), "(ref);\n});\n\nclickTest.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "after"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "document"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "body"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "removeChild"
        }), "(ref);\n});\n\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "clickTest"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "'will trigger on click outside'"
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createRoot"
        }), "(", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "dispose"
          }), ") =>"]
        }), "\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "new"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Promise"
        }), "<", jsx(_components.span, {
          className: "hljs-built_in",
          children: "void"
        }), ">(", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "resolve"
          }), ") =>"]
        }), " {\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "let"
        }), " clickedOutside = ", jsx(_components.span, {
          className: "hljs-literal",
          children: "false"
        }), ";\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "clickOutside"
        }), "(ref, ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " { clickedOutside = ", jsx(_components.span, {
          className: "hljs-literal",
          children: "true"
        }), "; });\n    ", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "document"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "body"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "addEventListener"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "'click'"
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n      assert.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "ok"
        }), "(clickedOutside);\n      ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "dispose"
        }), "();\n      ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "resolve"
        }), "();\n    });\n    fireEvent.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "click"
        }), "(", jsx(_components.span, {
          className: "hljs-variable language_",
          children: "document"
        }), ".", jsx(_components.span, {
          className: "hljs-property",
          children: "body"
        }), ");\n  })\n));\n\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "clickTest"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "'will not trigger on click inside'"
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createRoot"
        }), "(", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "dispose"
          }), ") =>"]
        }), "\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "new"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Promise"
        }), "<", jsx(_components.span, {
          className: "hljs-built_in",
          children: "void"
        }), ">(", jsxs(_components.span, {
          className: "hljs-function",
          children: ["(", jsx(_components.span, {
            className: "hljs-params",
            children: "resolve"
          }), ") =>"]
        }), " {\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "let"
        }), " clickedOutside = ", jsx(_components.span, {
          className: "hljs-literal",
          children: "false"
        }), ";\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "clickOutside"
        }), "(ref, ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " { clickedOutside = ", jsx(_components.span, {
          className: "hljs-literal",
          children: "true"
        }), "; });\n    ref.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "addEventListener"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "'click'"
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n      assert.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "is"
        }), "(clickedOutside, ", jsx(_components.span, {
          className: "hljs-literal",
          children: "false"
        }), ");\n      ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "dispose"
        }), "();\n      ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "resolve"
        }), "();\n    });\n    fireEvent.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "click"
        }), "(ref);\n  })\n));\n\nclickTest.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "run"
        }), "();\n"]
      })
    }), "\n", jsxs(_components.h3, {
      id: "컴포넌트-테스트",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#컴포넌트-테스트",
        children: "#"
      }), "컴포넌트 테스트"]
    }), "\n", jsx(_components.p, {
      children: "간단한 클릭 카운터 컴포넌트를 예로 들어 테스트해보겠습니다:"
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-comment",
          children: "// main.tsx"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { createSignal, ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Component"
        }), " } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-js\""
        }), ";\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "export"
        }), " ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Counter"
        }), ": ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Component"
        }), " = ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " [count, setCount] = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "createSignal"
        }), "(", jsx(_components.span, {
          className: "hljs-number",
          children: "0"
        }), ");\n\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "return"
        }), " ", jsxs(_components.span, {
          className: "xml",
          children: [jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "role"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "\"button\""
            }), " ", jsx(_components.span, {
              className: "hljs-attr",
              children: "onClick"
            }), "=", jsx(_components.span, {
              className: "hljs-string",
              children: "{()"
            }), " =>"]
          }), " setCount(c => c + 1)}>\n    Count: {count()}\n  ", jsxs(_components.span, {
            className: "hljs-tag",
            children: ["</", jsx(_components.span, {
              className: "hljs-name",
              children: "div"
            }), ">"]
          })]
        }), ";\n}\n"]
      })
    }), "\n", jsxs(_components.p, {
      children: ["아직 ", jsx(_components.code, {
        children: "solid-testing-library"
      }), "를 설치하지 않았다면 반드시 설치해야 합니다. 가장 중요한 헬퍼는 컴포넌트를 DOM에 렌더링하는 ", jsx(_components.code, {
        children: "render"
      }), ", 실제 사용자 이벤트와 유사한 방식으로 이벤트 디스패칭을 하는 ", jsx(_components.code, {
        children: "fireEvent"
      }), ", 전역 셀렉터를 제공하는 ", jsx(_components.code, {
        children: "screen"
      }), " 입니다. jest를 사용하는 경우, ", jsx(_components.code, {
        children: "@testing-library/jest-dom"
      }), "를 설치하고, 몇 가지 유용한 어설션을 설정하거나, 그렇지 않으면 위에서 설명한 ", jsx(_components.code, {
        children: "solid-dom-testing"
      }), "을 설치해야 합니다."]
    }), "\n", jsxs(_components.h4, {
      id: "jest--vitest-테스트-2",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#jest--vitest-테스트-2",
        children: "#"
      }), "Jest / vitest 테스트"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-comment",
          children: "// main.test.tsx"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Counter"
        }), " } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"./main\""
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { cleanup, fireEvent, render, screen } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-testing-library\""
        }), ";\n\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "describe"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"Counter\""
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "afterEach"
        }), "(cleanup);\n\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "test"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"it starts with zero\""
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "render"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "Counter"
            }), " />"]
          })
        }), ");\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " button = screen.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "getByRole"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"button\""
        }), ");\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "expect"
        }), "(button).", jsx(_components.span, {
          className: "hljs-title function_",
          children: "toBeInTheDocument"
        }), "();\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "expect"
        }), "(button).", jsx(_components.span, {
          className: "hljs-title function_",
          children: "toHaveTextContent"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"Count: 0\""
        }), ");\n  });\n\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "test"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"it increases its value on click\""
        }), ", ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "async"
        }), " () => {\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "render"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "Counter"
            }), " />"]
          })
        }), ");\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " button = screen.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "getByRole"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"button\""
        }), ");\n    fireEvent.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "click"
        }), "(button);\n    ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// the event loop takes one Promise to resolve to be finished"
        }), "\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "await"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Promise"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "resolve"
        }), "();\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "expect"
        }), "(button).", jsx(_components.span, {
          className: "hljs-title function_",
          children: "toHaveTextContent"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"Count: 1\""
        }), ");\n    fireEvent.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "click"
        }), "(button);\n    ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "await"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Promise"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "resolve"
        }), "();\n    ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "expect"
        }), "(button).", jsx(_components.span, {
          className: "hljs-title function_",
          children: "toHaveTextContent"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"Count: 2\""
        }), ");\n  });\n});\n"]
      })
    }), "\n", jsxs(_components.h4, {
      id: "uvu-테스트-2",
      children: [jsx(_components.a, {
        className: "header-anchor",
        href: "#uvu-테스트-2",
        children: "#"
      }), "uvu 테스트"]
    }), "\n", jsx(_components.pre, {
      children: jsxs(_components.code, {
        className: "hljs language-ts",
        children: [jsx(_components.span, {
          className: "hljs-comment",
          children: "// main.test.tsx"
        }), "\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { suite } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"uvu\""
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " * ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "as"
        }), " assert ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"uvu/assert\""
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Counter"
        }), " } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"main\""
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { fireEvent, render, screen } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-testing-library\""
        }), ";\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "import"
        }), " { isInDocument, hasTextContent } ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "from"
        }), " ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"solid-dom-testing\""
        }), ";\n\n\n", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " testCounter = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "suite"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"Counter\""
        }), ");\n\ntestCounter.", jsx(_components.span, {
          className: "hljs-property",
          children: "after"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "each"
        }), "(cleanup);\n\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "testCounter"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"it starts with zero\""
        }), ", ", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " {\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " { getByRole } = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "render"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "Counter"
            }), " />"]
          })
        }), ");\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " button = ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "getByRole"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"button\""
        }), ");\n  assert.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "ok"
        }), "(", jsx(_components.span, {
          className: "hljs-title function_",
          children: "isInDocument"
        }), "(button), ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"button not in dom\""
        }), ");\n  assert.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "ok"
        }), "(", jsx(_components.span, {
          className: "hljs-title function_",
          children: "hasTextContent"
        }), "(button, ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"Count: 0\""
        }), "), ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"wrong text content\""
        }), ");\n});\n\n", jsx(_components.span, {
          className: "hljs-title function_",
          children: "testCounter"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"it increases its value on click\""
        }), ", ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "async"
        }), " () => {\n  ", jsx(_components.span, {
          className: "hljs-title function_",
          children: "render"
        }), "(", jsx(_components.span, {
          className: "hljs-function",
          children: "() =>"
        }), " ", jsx(_components.span, {
          className: "xml",
          children: jsxs(_components.span, {
            className: "hljs-tag",
            children: ["<", jsx(_components.span, {
              className: "hljs-name",
              children: "Counter"
            }), " />"]
          })
        }), ");\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "const"
        }), " button = screen.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "getByRole"
        }), "(", jsx(_components.span, {
          className: "hljs-string",
          children: "\"button\""
        }), ");\n  fireEvent.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "click"
        }), "(button);\n  ", jsx(_components.span, {
          className: "hljs-comment",
          children: "// the event loop takes one Promise to resolve to be finished"
        }), "\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "await"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Promise"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "resolve"
        }), "();\n  assert.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "ok"
        }), "(", jsx(_components.span, {
          className: "hljs-title function_",
          children: "hasTextContent"
        }), "(button, ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"Count: 1\""
        }), "), ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"not count 1 after first click\""
        }), ");\n  fireEvent.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "click"
        }), "(button);\n  ", jsx(_components.span, {
          className: "hljs-keyword",
          children: "await"
        }), " ", jsx(_components.span, {
          className: "hljs-title class_",
          children: "Promise"
        }), ".", jsx(_components.span, {
          className: "hljs-title function_",
          children: "resolve"
        }), "();\n  assert.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "ok"
        }), "(", jsx(_components.span, {
          className: "hljs-title function_",
          children: "hasTextContent"
        }), "(button, ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"Count: 2\""
        }), "), ", jsx(_components.span, {
          className: "hljs-string",
          children: "\"not count 2 after first click\""
        }), ");\n});\n\ntestCounter.", jsx(_components.span, {
          className: "hljs-title function_",
          children: "run"
        }), "();\n"]
      })
    })]
  });
}
function MDXContent(props = {}) {
  const {wrapper: MDXLayout} = props.components || ({});
  return MDXLayout ? jsx(MDXLayout, Object.assign({}, props, {
    children: jsx(_createMdxContent, props)
  })) : _createMdxContent(props);
}

export { MDXContent as default, toc };
//# sourceMappingURL=testing-6df3943f.js.map
