{"componentChunkName":"component---src-templates-post-template-js","path":"/posts/3","result":{"data":{"markdownRemark":{"id":"b5e1d5ce-dfff-53c0-9b25-72ac908b679f","html":"<p>jest 에러 테스트를 만들다가 컨디션이 어떻게 된 건지 굉장히 헷갈리는 부분이 생겨서 정리를 해두려 한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token comment\">/* Errors can be handled using the .catch method.\nMake sure to add expect.assertions to verify that a certain number of assertions are called.\nOtherwise a fulfilled promise would not fail the test: */</span>\n\n<span class=\"token comment\">// using async/await.</span>\n<span class=\"token function\">it</span><span class=\"token punctuation\">(</span><span class=\"token string\">'tests error with async/await'</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  expect<span class=\"token punctuation\">.</span><span class=\"token function\">assertions</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">try</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">await</span> user<span class=\"token punctuation\">.</span><span class=\"token function\">getUserName</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span> <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>e<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toEqual</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n      error<span class=\"token punctuation\">:</span> <span class=\"token string\">'User with 1 not found.'</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>출처 : <a href=\"https://jestjs.io/docs/en/tutorial-async#error-handling\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://jestjs.io/docs/en/tutorial-async#error-handling</a></p>\n<p>jest 공식 문서에 나와있는 error handling 설명이다.\n내가 헷갈렸던 부분은 <code class=\"language-text\">expect.assertions(1);</code> 이 코드이다.</p>\n<blockquote>\n<p>Make sure to add expect.assertions to verify that a certain number of assertions are called. Otherwise a fulfilled promise would not fail the test</p>\n</blockquote>\n<p>설명을 보면 반드시 assertions 코드를 추가하라고 나와 있다.\n저게 무슨 말일까.. 이해가 가질 않았다.</p>\n<p>예제 코드를 돌려보고 이해할 수 있었다.</p>\n<div class=\"gatsby-highlight\" data-language=\"ts\"><pre class=\"language-ts\"><code class=\"language-ts\">describe<span class=\"token punctuation\">.</span><span class=\"token function\">only</span><span class=\"token punctuation\">(</span><span class=\"token string\">'buildWhereOptionsFromFiltersForExamQuestion2'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">test</span><span class=\"token punctuation\">(</span><span class=\"token string\">'throw when examID is invalid'</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    expect<span class=\"token punctuation\">.</span><span class=\"token function\">assertions</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">const</span> userModel <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> <span class=\"token function\">createSuperUser</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> examService <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">createServices</span><span class=\"token punctuation\">(</span>sequelize<span class=\"token punctuation\">,</span> userModel<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">try</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">await</span> examService<span class=\"token punctuation\">.</span><span class=\"token function\">buildWhereOptionsFromFiltersForExamQuestion</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> examID<span class=\"token punctuation\">:</span> <span class=\"token number\">1</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">toEqual</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">UserInputError</span><span class=\"token punctuation\">(</span><span class=\"token string\">'invalid examID'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>이 테스트는 examID가 유효하지 않을 때 발생시키는 에러를 테스트하는 것이다.\n근데 유효한 examID ‘1’을 부여하면 ?</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 764px;\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/765b04d7d65324bae8514ecf6d6db215/578a5/buildWhereOptionsFromFiltersForExamQuestion2.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 37.04188481675392%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAAAsSAAALEgHS3X78AAABUklEQVQoz01RWXaEIBD0MMmMooKKCy4g6izJS+bl/qepVM/kIx9Fd0NTVQ2JKUZsTYCvPWw5ITLfiZX1Ui0IjLNEQvpm1g37JtbT37nE0bzqROUOQ7+j7SKM9TBdQG5GaF7S5QytZ5TMDaOIG+VQqgFaIu8q5hmh/pCkXHp3RTPsUMOCjCg6uug2NI5C48GzDd10QVVNsBSzNSNzrSekOQmJc9Y/kZzTDqbyyGWM8Y51/0a73ZDGgPQe8b55vPmZoEu/Q6878hBwcjPO9YjSTCiEmMZSJYRkrevwJMw4Quc/4JYb4vGAm66o7Qrb06E70PfHq5fjqswh5xMIkXAImeTJiQ4rG6lCRTY22w8GPsEav+DGC2wb4cMntu2BhWIjRZp2pVCg4A2aH/EiHF6EUghZxR8s+VMVHUmtasaO4zUrEVkHFO3+3CuJgiaM7ImRf4S/gnziYT+zF2oAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n        <source\n          srcset=\"/static/765b04d7d65324bae8514ecf6d6db215/01472/buildWhereOptionsFromFiltersForExamQuestion2.webp 240w,\n/static/765b04d7d65324bae8514ecf6d6db215/222bd/buildWhereOptionsFromFiltersForExamQuestion2.webp 480w,\n/static/765b04d7d65324bae8514ecf6d6db215/954a9/buildWhereOptionsFromFiltersForExamQuestion2.webp 764w\"\n          sizes=\"(max-width: 764px) 100vw, 764px\"\n          type=\"image/webp\"\n        />\n        <source\n          srcset=\"/static/765b04d7d65324bae8514ecf6d6db215/0783d/buildWhereOptionsFromFiltersForExamQuestion2.png 240w,\n/static/765b04d7d65324bae8514ecf6d6db215/782f4/buildWhereOptionsFromFiltersForExamQuestion2.png 480w,\n/static/765b04d7d65324bae8514ecf6d6db215/578a5/buildWhereOptionsFromFiltersForExamQuestion2.png 764w\"\n          sizes=\"(max-width: 764px) 100vw, 764px\"\n          type=\"image/png\"\n        />\n        <img\n          class=\"gatsby-resp-image-image\"\n          src=\"/static/765b04d7d65324bae8514ecf6d6db215/578a5/buildWhereOptionsFromFiltersForExamQuestion2.png\"\n          alt=\"buildWhereOptionsFromFiltersForExamQuestion2\"\n          title=\"buildWhereOptionsFromFiltersForExamQuestion2\"\n          loading=\"lazy\"\n        />\n      </picture>\n  </a>\n    </span></p>\n<p>이러한 에러가 발생한다.\n“너가 의도한 one assertion이 아닌 zero assertion이 돌아왔다.”\n만약 assertions 코드가 없었더라면 우리는 내가 의도했던 에러가 발생했는지 안했는지 알 방도가 없다.</p>\n<p>예를 들어 assertions 코드가 없고, 에러를 발생시키지 않는 유효한 값이 들어가면 try 구문만 거치고 저 테스트는 끝났을 것이다. 에러 테스트를 제대로 하지 못하고 있는 것이다. 우리가 원했던 건 “내가 예상했던 에러가 제대로 발생하는가”를 확인하는 것이다.</p>\n<p>그렇다면 .rejects 함수는 어떨까?</p>\n<div class=\"gatsby-highlight\" data-language=\"ts\"><pre class=\"language-ts\"><code class=\"language-ts\">describe<span class=\"token punctuation\">.</span><span class=\"token function\">only</span><span class=\"token punctuation\">(</span><span class=\"token string\">'buildWhereOptionsFromFiltersForExamQuestion1'</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">test</span><span class=\"token punctuation\">(</span><span class=\"token string\">'throw when examID is invalid'</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">async</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> userModel <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> <span class=\"token function\">createSuperUser</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> examService <span class=\"token punctuation\">}</span> <span class=\"token operator\">=</span> <span class=\"token function\">createServices</span><span class=\"token punctuation\">(</span>sequelize<span class=\"token punctuation\">,</span> userModel<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">await</span> <span class=\"token function\">expect</span><span class=\"token punctuation\">(</span>\n      examService<span class=\"token punctuation\">.</span><span class=\"token function\">buildWhereOptionsFromFiltersForExamQuestion</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span> examID<span class=\"token punctuation\">:</span> <span class=\"token number\">1</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>rejects<span class=\"token punctuation\">.</span><span class=\"token function\">toEqual</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">new</span> <span class=\"token class-name\">UserInputError</span><span class=\"token punctuation\">(</span><span class=\"token string\">'invalid examID'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>assertions 코드를 추가하지 않아도 된다.\n그 이유는 rejects 함수 안에 assertions 기능이 내재되어 있기 때문이다.\nassertions 코드 없이 유효한 examID 값인 ‘1’을 부여해도 rejects 함수는 “너가 예상한 에러가 발생하지 않았다”는 것을 알려준다.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 767px;\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/bcd25c25e73568c815d4588ec53bf613/332aa/buildWhereOptionsFromFiltersForExamQuestion1.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 39.113428943937414%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAAAsSAAALEgHS3X78AAABYklEQVQoz22Ra3KDMAyEc5g2CXkAxhgwYCAmkDRpO9P7H2a7ckKn0+mPHcnGfFpJK697tGmLIq4x5QPGp4asQ68cmqSBZy7vHM+a7xq+l/zEe8u8TR1s0mIdFVjl5gTLj/KhtBNsc0HX31FWZ+yPFjEf7w8W0a4M2j719yzaCPA8f6H3H+iGO1w9I1MdElbO6FJgEqN9hZe1xusmx3prgiQXwOYJEgl0lRCw5WHPqOoLXPcW4Kb0KKoRrr/hxIISTTniyBHE7CbTA3Z0voB+HC7AOOthmmto1zYzEro7cF55MUIbHwCGMU07yrGYjKQObhdYcJgSJC3JnE7+ncBbcOP8J4bxTrczdUHpJmh3RumvqKcbcsLFccW5S4HoUD0cClCsSxuKmxSZwiOho1S3dPfQQdXY6QZR/pD8s/1vKQtAFiDLUGwlszMU71Q1ITEjlL0gldZ5n2iPY9yGdpdl/F7KN4oqBEYV0LBFAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n        <source\n          srcset=\"/static/bcd25c25e73568c815d4588ec53bf613/01472/buildWhereOptionsFromFiltersForExamQuestion1.webp 240w,\n/static/bcd25c25e73568c815d4588ec53bf613/222bd/buildWhereOptionsFromFiltersForExamQuestion1.webp 480w,\n/static/bcd25c25e73568c815d4588ec53bf613/d6cc6/buildWhereOptionsFromFiltersForExamQuestion1.webp 767w\"\n          sizes=\"(max-width: 767px) 100vw, 767px\"\n          type=\"image/webp\"\n        />\n        <source\n          srcset=\"/static/bcd25c25e73568c815d4588ec53bf613/0783d/buildWhereOptionsFromFiltersForExamQuestion1.png 240w,\n/static/bcd25c25e73568c815d4588ec53bf613/782f4/buildWhereOptionsFromFiltersForExamQuestion1.png 480w,\n/static/bcd25c25e73568c815d4588ec53bf613/332aa/buildWhereOptionsFromFiltersForExamQuestion1.png 767w\"\n          sizes=\"(max-width: 767px) 100vw, 767px\"\n          type=\"image/png\"\n        />\n        <img\n          class=\"gatsby-resp-image-image\"\n          src=\"/static/bcd25c25e73568c815d4588ec53bf613/332aa/buildWhereOptionsFromFiltersForExamQuestion1.png\"\n          alt=\"buildWhereOptionsFromFiltersForExamQuestion1\"\n          title=\"buildWhereOptionsFromFiltersForExamQuestion1\"\n          loading=\"lazy\"\n        />\n      </picture>\n  </a>\n    </span></p>\n<p>“Received promise resolved instead of rejected” 불합격으로 처리된 것이 아닌 해결된 promise가 돌아왔다는 것이다.\n에러(불합격)를 예상(expect)했지만 말이다.</p>","fields":{"slug":"/posts/3","tagSlugs":null},"frontmatter":{"date":"2019-11-06","description":"","tags":null,"title":"Jest error handling, .rejects function"}}},"pageContext":{"isCreatedByStatefulCreatePages":false,"slug":"/posts/3"}}}