CINXE.COM

<!doctype html><html lang="en"><head><title data-rh="true">My First Step into Unit Testing in Flutter: Simple Explanations | by Surajbhandari | Flutter Community | Nov, 2024 | Medium</title><meta data-rh="true" charset="utf-8"/><meta data-rh="true" name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1,maximum-scale=1"/><meta data-rh="true" name="theme-color" content="#000000"/><meta data-rh="true" name="twitter:app:name:iphone" content="Medium"/><meta data-rh="true" name="twitter:app:id:iphone" content="828256236"/><meta data-rh="true" property="al:ios:app_name" content="Medium"/><meta data-rh="true" property="al:ios:app_store_id" content="828256236"/><meta data-rh="true" property="al:android:package" content="com.medium.reader"/><meta data-rh="true" property="fb:app_id" content="542599432471018"/><meta data-rh="true" property="og:site_name" content="Medium"/><meta data-rh="true" property="og:type" content="article"/><meta data-rh="true" property="article:published_time" content="2024-11-24T18:23:39.331Z"/><meta data-rh="true" name="title" content="My First Step into Unit Testing in Flutter: Simple Explanations | by Surajbhandari | Flutter Community | Nov, 2024 | Medium"/><meta data-rh="true" property="og:title" content="My First Step into Unit Testing in Flutter: Simple Explanations"/><meta data-rh="true" property="al:android:url" content="medium://p/64e0c4bc4d1a"/><meta data-rh="true" property="al:ios:url" content="medium://p/64e0c4bc4d1a"/><meta data-rh="true" property="al:android:app_name" content="Medium"/><meta data-rh="true" name="description" content="I have been involved with Flutter for the past three years. I was busy running a race for a good Flutter developer. One day I heard about Test Driven Development (TDD), which is an approach to…"/><meta data-rh="true" property="og:description" content="Testing used to be a boring side for me."/><meta data-rh="true" property="og:url" content="https://medium.com/flutter-community/my-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a"/><meta data-rh="true" property="al:web:url" content="https://medium.com/flutter-community/my-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a"/><meta data-rh="true" property="og:image" content="https://miro.medium.com/v2/resize:fit:1080/1*iHGUNxLXc7mKwpqKw5JAOw.png"/><meta data-rh="true" property="article:author" content="https://medium.com/@surajbhandari5502"/><meta data-rh="true" name="author" content="Surajbhandari"/><meta data-rh="true" name="robots" content="index,noarchive,follow,max-image-preview:large"/><meta data-rh="true" name="referrer" content="unsafe-url"/><meta data-rh="true" property="twitter:title" content="My First Step into Unit Testing in Flutter: Simple Explanations"/><meta data-rh="true" name="twitter:site" content="@FlutterComm"/><meta data-rh="true" name="twitter:app:url:iphone" content="medium://p/64e0c4bc4d1a"/><meta data-rh="true" property="twitter:description" content="Testing used to be a boring side for me."/><meta data-rh="true" name="twitter:image:src" content="https://miro.medium.com/v2/resize:fit:1080/1*iHGUNxLXc7mKwpqKw5JAOw.png"/><meta data-rh="true" name="twitter:card" content="summary_large_image"/><meta data-rh="true" name="twitter:label1" content="Reading time"/><meta data-rh="true" name="twitter:data1" content="8 min read"/><link data-rh="true" rel="icon" href="https://miro.medium.com/v2/5d8de952517e8160e40ef9841c781cdc14a5db313057fa3c3de41c6f5b494b19"/><link data-rh="true" rel="search" type="application/opensearchdescription+xml" title="Medium" href="/osd.xml"/><link data-rh="true" rel="apple-touch-icon" sizes="152x152" href="https://miro.medium.com/v2/resize:fill:304:304/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="120x120" href="https://miro.medium.com/v2/resize:fill:240:240/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="76x76" href="https://miro.medium.com/v2/resize:fill:152:152/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="apple-touch-icon" sizes="60x60" href="https://miro.medium.com/v2/resize:fill:120:120/10fd5c419ac61637245384e7099e131627900034828f4f386bdaa47a74eae156"/><link data-rh="true" rel="mask-icon" href="https://miro.medium.com/v2/resize:fill:1000:1000/7*GAOKVe--MXbEJmV9230oOQ.png" color="#171717"/><link data-rh="true" rel="preconnect" href="https://glyph.medium.com" crossOrigin=""/><link data-rh="true" id="glyph_preload_link" rel="preload" as="style" type="text/css" href="https://glyph.medium.com/css/unbound.css"/><link data-rh="true" id="glyph_link" rel="stylesheet" type="text/css" href="https://glyph.medium.com/css/unbound.css"/><link data-rh="true" rel="author" href="https://medium.com/@surajbhandari5502"/><link data-rh="true" rel="canonical" href="https://medium.com/flutter-community/my-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a"/><link data-rh="true" rel="alternate" href="android-app://com.medium.reader/https/medium.com/p/64e0c4bc4d1a"/><script data-rh="true" type="application/ld+json">{"@context":"http:\u002F\u002Fschema.org","@type":"NewsArticle","image":["https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:1200\u002F1*iHGUNxLXc7mKwpqKw5JAOw.png"],"url":"https:\u002F\u002Fmedium.com\u002Fflutter-community\u002Fmy-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a","dateCreated":"2024-11-12T15:32:48.345Z","datePublished":"2024-11-12T15:32:48.345Z","dateModified":"2024-11-24T18:23:39.331Z","headline":"My First Step into Unit Testing in Flutter: Simple Explanations","name":"My First Step into Unit Testing in Flutter: Simple Explanations","description":"I have been involved with Flutter for the past three years. I was busy running a race for a good Flutter developer. One day I heard about Test Driven Development (TDD), which is an approach to…","identifier":"64e0c4bc4d1a","author":{"@type":"Person","name":"Surajbhandari","url":"https:\u002F\u002Fmedium.com\u002F@surajbhandari5502"},"creator":["Surajbhandari"],"publisher":{"@type":"Organization","name":"Flutter Community","url":"https:\u002F\u002Fmedium.com\u002Fflutter-community","logo":{"@type":"ImageObject","width":272,"height":60,"url":"https:\u002F\u002Fmiro.medium.com\u002Fv2\u002Fresize:fit:544\u002F7*V1_7XP4snlmqrc_0Njontw.png"}},"mainEntityOfPage":"https:\u002F\u002Fmedium.com\u002Fflutter-community\u002Fmy-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a"}</script><style type="text/css" data-fela-rehydration="575" data-fela-type="STATIC">html{box-sizing:border-box;-webkit-text-size-adjust:100%}*, *:before, *:after{box-sizing:inherit}body{margin:0;padding:0;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;color:rgba(0,0,0,0.8);position:relative;min-height:100vh}h1, h2, h3, h4, h5, h6, dl, dd, ol, ul, menu, figure, blockquote, p, pre, form{margin:0}menu, ol, ul{padding:0;list-style:none;list-style-image:none}main{display:block}a{color:inherit;text-decoration:none}a, button, input{-webkit-tap-highlight-color:transparent}img, svg{vertical-align:middle}button{background:transparent;overflow:visible}button, input, optgroup, select, textarea{margin:0}:root{--reach-tabs:1;--reach-menu-button:1}#speechify-root{font-family:Sohne, sans-serif}div[data-popper-reference-hidden="true"]{visibility:hidden;pointer-events:none}.grecaptcha-badge{visibility:hidden} /*XCode style (c) Angel Garcia <angelgarcia.mail@gmail.com>*/.hljs {background: #fff;color: black; }/* Gray DOCTYPE selectors like WebKit */ .xml .hljs-meta {color: #c0c0c0; }.hljs-comment, .hljs-quote {color: #007400; }.hljs-tag, .hljs-attribute, .hljs-keyword, .hljs-selector-tag, .hljs-literal, .hljs-name {color: #aa0d91; }.hljs-variable, .hljs-template-variable {color: #3F6E74; }.hljs-code, .hljs-string, .hljs-meta .hljs-string {color: #c41a16; }.hljs-regexp, .hljs-link {color: #0E0EFF; }.hljs-title, .hljs-symbol, .hljs-bullet, .hljs-number {color: #1c00cf; }.hljs-section, .hljs-meta {color: #643820; }.hljs-title.class_, .hljs-class .hljs-title, .hljs-type, .hljs-built_in, .hljs-params {color: #5c2699; }.hljs-attr {color: #836C28; }.hljs-subst {color: #000; }.hljs-formula {background-color: #eee;font-style: italic; }.hljs-addition {background-color: #baeeba; }.hljs-deletion {background-color: #ffc8bd; }.hljs-selector-id, .hljs-selector-class {color: #9b703f; }.hljs-doctag, .hljs-strong {font-weight: bold; }.hljs-emphasis {font-style: italic; } </style><style type="text/css" data-fela-rehydration="575" data-fela-type="KEYFRAME">@-webkit-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@-moz-keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}@keyframes k1{0%{opacity:0.8}50%{opacity:0.5}100%{opacity:0.8}}</style><style type="text/css" data-fela-rehydration="575" data-fela-type="RULE">.a{font-family:medium-content-sans-serif-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif}.b{font-weight:400}.c{background-color:rgba(255, 255, 255, 1)}.l{display:block}.m{position:sticky}.n{top:0}.o{z-index:500}.p{padding:0 24px}.q{align-items:center}.r{border-bottom:solid 1px #F2F2F2}.y{height:41px}.z{line-height:20px}.ab{display:flex}.ac{height:57px}.ae{flex:1 0 auto}.af{color:inherit}.ag{fill:inherit}.ah{font-size:inherit}.ai{border:inherit}.aj{font-family:inherit}.ak{letter-spacing:inherit}.al{font-weight:inherit}.am{padding:0}.an{margin:0}.ao{cursor:pointer}.ap:disabled{cursor:not-allowed}.aq:disabled{color:#6B6B6B}.ar:disabled{fill:#6B6B6B}.au{width:auto}.av path{fill:#242424}.aw{height:25px}.ax{margin-left:16px}.ay{border:none}.az{border-radius:20px}.ba{width:240px}.bb{background:#F9F9F9}.bc path{fill:#6B6B6B}.be{outline:none}.bf{font-family:sohne, "Helvetica Neue", Helvetica, Arial, sans-serif}.bg{font-size:14px}.bh{width:100%}.bi{padding:10px 20px 10px 0}.bj{background-color:transparent}.bk{color:#242424}.bl::placeholder{color:#6B6B6B}.bm{display:inline-block}.bn{margin-left:12px}.bo{margin-right:12px}.bp{border-radius:4px}.bq{margin-left:24px}.br{height:24px}.bx{background-color:#F9F9F9}.by{border-radius:50%}.bz{height:32px}.ca{width:32px}.cb{justify-content:center}.ch{max-width:680px}.ci{min-width:0}.cj{animation:k1 1.2s ease-in-out infinite}.ck{height:100vh}.cl{margin-bottom:16px}.cm{margin-top:48px}.cn{align-items:flex-start}.co{flex-direction:column}.cp{justify-content:space-between}.cq{margin-bottom:24px}.cw{width:80%}.cx{background-color:#F2F2F2}.dd{height:44px}.de{width:44px}.df{margin:auto 0}.dg{margin-bottom:4px}.dh{height:16px}.di{width:120px}.dj{width:80px}.dp{margin-bottom:8px}.dq{width:96%}.dr{width:98%}.ds{width:81%}.dt{margin-left:8px}.du{color:#6B6B6B}.dv{font-size:13px}.dw{height:100%}.ep{color:#FFFFFF}.eq{fill:#FFFFFF}.er{background:rgba(0, 142, 231, 1)}.es{border-color:rgba(0, 142, 231, 1)}.ew:disabled{cursor:inherit !important}.ex:disabled{opacity:0.3}.ey:disabled:hover{background:rgba(0, 142, 231, 1)}.ez:disabled:hover{border-color:rgba(0, 142, 231, 1)}.fa{border-radius:99em}.fb{border-width:1px}.fc{border-style:solid}.fd{box-sizing:border-box}.fe{text-decoration:none}.ff{text-align:center}.fi{margin-right:32px}.fj{position:relative}.fk{fill:#6B6B6B}.fn{background:transparent}.fo svg{margin-left:4px}.fp svg{fill:#6B6B6B}.fr{box-shadow:inset 0 0 0 1px rgba(0, 0, 0, 0.05)}.fs{position:absolute}.fz{margin:0 24px}.gd{background:rgba(255, 255, 255, 1)}.ge{border:1px solid #F2F2F2}.gf{box-shadow:0 1px 4px #F2F2F2}.gg{max-height:100vh}.gh{overflow-y:auto}.gi{left:0}.gj{top:calc(100vh + 100px)}.gk{bottom:calc(100vh + 100px)}.gl{width:10px}.gm{pointer-events:none}.gn{word-break:break-word}.go{word-wrap:break-word}.gp:after{display:block}.gq:after{content:""}.gr:after{clear:both}.gs{line-height:1.23}.gt{letter-spacing:0}.gu{font-style:normal}.gv{font-weight:700}.hq{margin-bottom:-0.27em}.hr{line-height:1.394}.im{align-items:baseline}.in{width:48px}.io{height:48px}.ip{border:2px solid rgba(255, 255, 255, 1)}.iq{z-index:0}.ir{box-shadow:none}.is{border:1px solid rgba(0, 0, 0, 0.05)}.it{margin-left:-12px}.iu{width:28px}.iv{height:28px}.iw{z-index:1}.ix{width:24px}.iy{margin-bottom:2px}.iz{flex-wrap:nowrap}.ja{font-size:16px}.jb{line-height:24px}.jd{margin:0 8px}.je{display:inline}.jf{color:rgba(0, 142, 231, 1)}.jg{fill:rgba(0, 142, 231, 1)}.jj{flex:0 0 auto}.jm{flex-wrap:wrap}.jp{white-space:pre-wrap}.jq{margin-right:4px}.jr{overflow:hidden}.js{max-height:20px}.jt{text-overflow:ellipsis}.ju{display:-webkit-box}.jv{-webkit-line-clamp:1}.jw{-webkit-box-orient:vertical}.jx{word-break:break-all}.jz{padding-left:8px}.ka{padding-right:8px}.lb> *{flex-shrink:0}.lc{overflow-x:scroll}.ld::-webkit-scrollbar{display:none}.le{scrollbar-width:none}.lf{-ms-overflow-style:none}.lg{width:74px}.lh{flex-direction:row}.li{z-index:2}.ll{-webkit-user-select:none}.lm{border:0}.ln{fill:rgba(117, 117, 117, 1)}.lq{outline:0}.lr{user-select:none}.ls> svg{pointer-events:none}.mb{cursor:progress}.mc{opacity:1}.md{padding:4px 0}.mg{margin-top:0px}.mh{width:16px}.mj{display:inline-flex}.mp{max-width:100%}.mq{padding:8px 2px}.mr svg{color:#6B6B6B}.ni{margin-left:auto}.nj{margin-right:auto}.nk{max-width:1080px}.nq{clear:both}.ns{cursor:zoom-in}.nt{z-index:auto}.nv{height:auto}.nw{margin-top:10px}.nx{max-width:728px}.oa{line-height:1.58}.ob{letter-spacing:-0.004em}.oc{font-family:source-serif-pro, Georgia, Cambria, "Times New Roman", Times, serif}.ov{margin-bottom:-0.46em}.ow{box-shadow:inset 3px 0 0 0 #242424}.ox{padding-left:23px}.oy{margin-left:-20px}.oz{font-style:italic}.pa{max-width:498px}.pb{text-decoration:underline}.pc{padding:2px 4px}.pd{font-size:75%}.pe> strong{font-family:inherit}.pf{font-family:source-code-pro, Menlo, Monaco, "Courier New", Courier, monospace}.pg{max-width:570px}.ph{clear:left}.pi{float:left}.pj{font-size:66px}.pk{line-height:.83}.pq{list-style-type:disc}.pr{margin-left:30px}.ps{padding-left:0px}.py{overflow-x:auto}.pz{padding:32px}.qa{border:1px solid #E5E5E5}.qb{line-height:1.4}.qc{letter-spacing:-0.022em}.qd{margin-top:-0.2em}.qe{margin-bottom:-0.2em}.qf{white-space:pre}.qg{min-width:fit-content}.qh{max-width:1289px}.qi{max-width:640px}.qj{max-width:734px}.qk{line-height:1.18}.ql{font-weight:600}.rb{margin-bottom:-0.31em}.rh{list-style-type:decimal}.ri{line-height:1.12}.rz{margin-bottom:-0.28em}.sa{margin-bottom:26px}.sb{margin-top:6px}.sc{margin-top:8px}.sd{margin-right:8px}.se{padding:8px 16px}.sf{border-radius:100px}.sg{transition:background 300ms ease}.si{white-space:nowrap}.sj{border-top:none}.sp{height:52px}.sq{max-height:52px}.sr{box-sizing:content-box}.ss{position:static}.su{max-width:155px}.ta{margin-right:20px}.tg{margin-bottom:48px}.tu{border-radius:2px}.tw{height:64px}.tx{width:64px}.ty{align-self:flex-end}.tz{flex:1 1 auto}.uf{padding-right:4px}.ug{font-weight:500}.un{margin-top:16px}.uo{color:rgba(255, 255, 255, 1)}.up{fill:rgba(255, 255, 255, 1)}.uq{background:rgba(25, 25, 25, 1)}.ur{border-color:rgba(25, 25, 25, 1)}.uu:disabled{opacity:0.1}.uv:disabled:hover{background:rgba(25, 25, 25, 1)}.uw:disabled:hover{border-color:rgba(25, 25, 25, 1)}.ux{height:0px}.uy{border-bottom:solid 1px #E5E5E5}.uz{margin-top:56px}.va{margin-top:72px}.vb{padding:24px 0}.vc{margin-bottom:0px}.vd{margin-right:16px}.as:hover:not(:disabled){color:rgba(25, 25, 25, 1)}.at:hover:not(:disabled){fill:rgba(25, 25, 25, 1)}.et:hover{background:rgba(28, 122, 192, 1)}.eu:hover{border-color:rgba(28, 122, 192, 1)}.ev:hover{cursor:pointer}.fl:hover{color:#242424}.fm:hover{fill:#242424}.fq:hover svg{fill:#242424}.ft:hover{background-color:rgba(0, 0, 0, 0.1)}.jc:hover{text-decoration:underline}.jh:hover:not(:disabled){color:rgba(28, 122, 192, 1)}.ji:hover:not(:disabled){fill:rgba(28, 122, 192, 1)}.lp:hover{fill:rgba(8, 8, 8, 1)}.me:hover{fill:#000000}.mf:hover p{color:#000000}.mi:hover{color:#000000}.ms:hover svg{color:#000000}.sh:hover{background-color:#F2F2F2}.tv:hover{background-color:none}.us:hover{background:#000000}.ut:hover{border-color:#242424}.bd:focus-within path{fill:#242424}.lo:focus{fill:rgba(8, 8, 8, 1)}.mt:focus svg{color:#000000}.nu:focus{transform:scale(1.01)}.lt:active{border-style:none}</style><style type="text/css" data-fela-rehydration="575" data-fela-type="RULE" media="all and (min-width: 1080px)">.d{display:none}.bw{width:64px}.cg{margin:0 64px}.cv{height:48px}.dc{margin-bottom:52px}.do{margin-bottom:48px}.ef{font-size:14px}.eg{line-height:20px}.em{font-size:13px}.eo{padding:5px 12px}.fh{display:flex}.fy{margin-bottom:68px}.gc{max-width:680px}.hm{font-size:42px}.hn{margin-top:1.19em}.ho{line-height:52px}.hp{letter-spacing:-0.011em}.ie{font-size:22px}.if{margin-top:0.92em}.ig{line-height:28px}.il{align-items:center}.kn{border-top:solid 1px #F2F2F2}.ko{border-bottom:solid 1px #F2F2F2}.kp{margin:32px 0 0}.kq{padding:3px 8px}.kz> *{margin-right:24px}.la> :last-child{margin-right:0}.ma{margin-top:0px}.mo{margin:0}.np{margin-top:56px}.or{font-size:20px}.os{margin-top:2.14em}.ot{line-height:32px}.ou{letter-spacing:-0.003em}.pp{padding-top:7px}.px{margin-top:1.14em}.qy{margin-top:1.72em}.qz{line-height:24px}.ra{letter-spacing:0}.rg{margin-top:0.94em}.rv{font-size:24px}.rw{margin-top:1.95em}.rx{line-height:30px}.ry{letter-spacing:-0.016em}.so{margin-bottom:88px}.sz{display:inline-block}.tf{padding-top:72px}.th{flex-direction:row}.tk{margin-bottom:0}.tl{margin-right:20px}.ua{max-width:500px}</style><style type="text/css" data-fela-rehydration="575" data-fela-type="RULE" media="all and (max-width: 1079.98px)">.e{display:none}.lz{margin-top:0px}.ny{margin-left:auto}.nz{text-align:center}.sy{display:inline-block}</style><style type="text/css" data-fela-rehydration="575" data-fela-type="RULE" media="all and (max-width: 903.98px)">.f{display:none}.ly{margin-top:0px}.sx{display:inline-block}</style><style type="text/css" data-fela-rehydration="575" data-fela-type="RULE" media="all and (max-width: 727.98px)">.g{display:none}.lw{margin-top:0px}.lx{margin-right:0px}.sw{display:inline-block}</style><style type="text/css" data-fela-rehydration="575" data-fela-type="RULE" media="all and (max-width: 551.98px)">.h{display:none}.s{display:flex}.t{justify-content:space-between}.bs{width:24px}.cc{margin:0 24px}.cr{height:40px}.cy{margin-bottom:44px}.dk{margin-bottom:32px}.dx{font-size:13px}.dy{line-height:20px}.eh{padding:0px 8px 1px}.fu{margin-bottom:4px}.gw{font-size:32px}.gx{margin-top:1.01em}.gy{line-height:38px}.gz{letter-spacing:-0.014em}.hs{font-size:18px}.ht{margin-top:0.79em}.hu{line-height:24px}.ih{align-items:flex-start}.jk{flex-direction:column}.jn{margin-bottom:2px}.kb{margin:24px -24px 0}.kc{padding:0}.kr> *{margin-right:8px}.ks> :last-child{margin-right:24px}.lj{margin-left:0px}.lu{margin-top:0px}.lv{margin-right:0px}.mk{margin:0}.mu{border:1px solid #F2F2F2}.mv{border-radius:99em}.mw{padding:0px 16px 0px 12px}.mx{height:38px}.my{align-items:center}.na svg{margin-right:8px}.nl{margin-top:40px}.od{margin-top:1.56em}.oe{line-height:28px}.of{letter-spacing:-0.003em}.pl{padding-top:0}.pt{margin-top:1.34em}.qm{font-size:16px}.qn{margin-top:1.23em}.qo{letter-spacing:0}.rc{margin-top:0.67em}.rj{font-size:20px}.rk{margin-top:1.2em}.sk{margin-bottom:80px}.sv{display:inline-block}.tb{padding-top:48px}.ts{margin-bottom:20px}.tt{margin-right:0}.ue{max-width:100%}.uh{font-size:24px}.ui{line-height:30px}.uj{letter-spacing:-0.016em}.mz:hover{border-color:#E5E5E5}</style><style type="text/css" data-fela-rehydration="575" data-fela-type="RULE" media="all and (min-width: 904px) and (max-width: 1079.98px)">.i{display:none}.bv{width:64px}.cf{margin:0 64px}.cu{height:48px}.db{margin-bottom:52px}.dn{margin-bottom:48px}.ed{font-size:14px}.ee{line-height:20px}.ek{font-size:13px}.el{padding:5px 12px}.fg{display:flex}.fx{margin-bottom:68px}.gb{max-width:680px}.hi{font-size:42px}.hj{margin-top:1.19em}.hk{line-height:52px}.hl{letter-spacing:-0.011em}.ib{font-size:22px}.ic{margin-top:0.92em}.id{line-height:28px}.ik{align-items:center}.kj{border-top:solid 1px #F2F2F2}.kk{border-bottom:solid 1px #F2F2F2}.kl{margin:32px 0 0}.km{padding:3px 8px}.kx> *{margin-right:24px}.ky> :last-child{margin-right:0}.mn{margin:0}.no{margin-top:56px}.on{font-size:20px}.oo{margin-top:2.14em}.op{line-height:32px}.oq{letter-spacing:-0.003em}.po{padding-top:7px}.pw{margin-top:1.14em}.qv{margin-top:1.72em}.qw{line-height:24px}.qx{letter-spacing:0}.rf{margin-top:0.94em}.rr{font-size:24px}.rs{margin-top:1.95em}.rt{line-height:30px}.ru{letter-spacing:-0.016em}.sn{margin-bottom:88px}.te{padding-top:72px}.ti{flex-direction:row}.tm{margin-bottom:0}.tn{margin-right:20px}.ub{max-width:500px}</style><style type="text/css" data-fela-rehydration="575" data-fela-type="RULE" media="all and (min-width: 728px) and (max-width: 903.98px)">.j{display:none}.w{display:flex}.x{justify-content:space-between}.bu{width:64px}.ce{margin:0 48px}.ct{height:48px}.da{margin-bottom:52px}.dm{margin-bottom:48px}.eb{font-size:13px}.ec{line-height:20px}.ej{padding:0px 8px 1px}.fw{margin-bottom:68px}.ga{max-width:680px}.he{font-size:42px}.hf{margin-top:1.19em}.hg{line-height:52px}.hh{letter-spacing:-0.011em}.hy{font-size:22px}.hz{margin-top:0.92em}.ia{line-height:28px}.ij{align-items:center}.kf{border-top:solid 1px #F2F2F2}.kg{border-bottom:solid 1px #F2F2F2}.kh{margin:32px 0 0}.ki{padding:3px 8px}.kv> *{margin-right:24px}.kw> :last-child{margin-right:0}.mm{margin:0}.nn{margin-top:56px}.oj{font-size:20px}.ok{margin-top:2.14em}.ol{line-height:32px}.om{letter-spacing:-0.003em}.pn{padding-top:7px}.pv{margin-top:1.14em}.qs{margin-top:1.72em}.qt{line-height:24px}.qu{letter-spacing:0}.re{margin-top:0.94em}.rn{font-size:24px}.ro{margin-top:1.95em}.rp{line-height:30px}.rq{letter-spacing:-0.016em}.sm{margin-bottom:88px}.td{padding-top:72px}.tj{flex-direction:row}.to{margin-bottom:0}.tp{margin-right:20px}.uc{max-width:500px}</style><style type="text/css" data-fela-rehydration="575" data-fela-type="RULE" media="all and (min-width: 552px) and (max-width: 727.98px)">.k{display:none}.u{display:flex}.v{justify-content:space-between}.bt{width:24px}.cd{margin:0 24px}.cs{height:40px}.cz{margin-bottom:44px}.dl{margin-bottom:32px}.dz{font-size:13px}.ea{line-height:20px}.ei{padding:0px 8px 1px}.fv{margin-bottom:4px}.ha{font-size:32px}.hb{margin-top:1.01em}.hc{line-height:38px}.hd{letter-spacing:-0.014em}.hv{font-size:18px}.hw{margin-top:0.79em}.hx{line-height:24px}.ii{align-items:flex-start}.jl{flex-direction:column}.jo{margin-bottom:2px}.kd{margin:24px 0 0}.ke{padding:0}.kt> *{margin-right:8px}.ku> :last-child{margin-right:8px}.lk{margin-left:0px}.ml{margin:0}.nb{border:1px solid #F2F2F2}.nc{border-radius:99em}.nd{padding:0px 16px 0px 12px}.ne{height:38px}.nf{align-items:center}.nh svg{margin-right:8px}.nm{margin-top:40px}.og{margin-top:1.56em}.oh{line-height:28px}.oi{letter-spacing:-0.003em}.pm{padding-top:0}.pu{margin-top:1.34em}.qp{font-size:16px}.qq{margin-top:1.23em}.qr{letter-spacing:0}.rd{margin-top:0.67em}.rl{font-size:20px}.rm{margin-top:1.2em}.sl{margin-bottom:80px}.tc{padding-top:48px}.tq{margin-bottom:20px}.tr{margin-right:0}.ud{max-width:100%}.uk{font-size:24px}.ul{line-height:30px}.um{letter-spacing:-0.016em}.ng:hover{border-color:#E5E5E5}</style><style type="text/css" data-fela-rehydration="575" data-fela-type="RULE" media="print">.st{display:none}</style><style type="text/css" data-fela-rehydration="575" data-fela-type="RULE" media="(orientation: landscape) and (max-width: 903.98px)">.jy{max-height:none}</style><style type="text/css" data-fela-rehydration="575" data-fela-type="RULE" media="(prefers-reduced-motion: no-preference)">.nr{transition:transform 300ms cubic-bezier(0.2, 0, 0.2, 1)}</style></head><body><div id="root"><div class="a b c"><div class="d e f g h i j k"></div><script>document.domain = document.domain;</script><div class="l c"><div class="l m n o c"><div class="p q r s t u v w x i d y z"><a class="du ag dv bf ak b am an ao ap aq ar as at s u w i d q dw z" href="https://rsci.app.link/?%24canonical_url=https%3A%2F%2Fmedium.com%2Fp%2F64e0c4bc4d1a&amp;%7Efeature=LoOpenInAppButton&amp;%7Echannel=ShowPostUnderCollection&amp;source=---top_nav_layout_nav----------------------------------" rel="noopener follow">Open in app<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10" fill="none" viewBox="0 0 10 10" class="dt"><path fill="currentColor" d="M.985 8.485a.375.375 0 1 0 .53.53zM8.75 1.25h.375A.375.375 0 0 0 8.75.875zM8.375 6.5a.375.375 0 1 0 .75 0zM3.5.875a.375.375 0 1 0 0 .75zm-1.985 8.14 7.5-7.5-.53-.53-7.5 7.5zm6.86-7.765V6.5h.75V1.25zM3.5 1.625h5.25v-.75H3.5z"></path></svg></a><div class="ab q"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><button class="bf b dx dy eh dz ea ei eb ec ej ek ee el em eg eo ep eq er es et eu ev ew ex ey ez fa fb fc fd bm fe ff" data-testid="headerSignUpButton">Sign up</button></span></p><div class="ax l"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSignInButton" rel="noopener follow" href="/m/signin?operation=login&amp;redirect=https%3A%2F%2Fmedium.com%2Fflutter-community%2Fmy-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a&amp;source=post_page---top_nav_layout_nav-----------------------global_nav-----------">Sign in</a></span></p></div></div></div><div class="p q r ab ac"><div class="ab q ae"><a class="af ag ah ai aj ak al am an ao ap aq ar as at ab" aria-label="Homepage" data-testid="headerMediumLogo" rel="noopener follow" href="/?source=---top_nav_layout_nav----------------------------------"><svg xmlns="http://www.w3.org/2000/svg" width="719" height="160" fill="none" viewBox="0 0 719 160" class="au av aw"><path fill="#242424" d="m174.104 9.734.215-.047V8.02H130.39L89.6 103.89 48.81 8.021H1.472v1.666l.212.047c8.018 1.81 12.09 4.509 12.09 14.242V137.93c0 9.734-4.087 12.433-12.106 14.243l-.212.047v1.671h32.118v-1.665l-.213-.048c-8.018-1.809-12.089-4.509-12.089-14.242V30.586l52.399 123.305h2.972l53.925-126.743V140.75c-.687 7.688-4.721 10.062-11.982 11.701l-.215.05v1.652h55.948v-1.652l-.215-.05c-7.269-1.639-11.4-4.013-12.087-11.701l-.037-116.774h.037c0-9.733 4.071-12.432 12.087-14.242m25.555 75.488c.915-20.474 8.268-35.252 20.606-35.507 3.806.063 6.998 1.312 9.479 3.714 5.272 5.118 7.751 15.812 7.368 31.793zm-.553 5.77h65.573v-.275c-.186-15.656-4.721-27.834-13.466-36.196-7.559-7.227-18.751-11.203-30.507-11.203h-.263c-6.101 0-13.584 1.48-18.909 4.16-6.061 2.807-11.407 7.003-15.855 12.511-7.161 8.874-11.499 20.866-12.554 34.343q-.05.606-.092 1.212a50 50 0 0 0-.065 1.151 85.807 85.807 0 0 0-.094 5.689c.71 30.524 17.198 54.917 46.483 54.917 25.705 0 40.675-18.791 44.407-44.013l-1.886-.664c-6.557 13.556-18.334 21.771-31.738 20.769-18.297-1.369-32.314-19.922-31.042-42.395m139.722 41.359c-2.151 5.101-6.639 7.908-12.653 7.908s-11.513-4.129-15.418-11.63c-4.197-8.053-6.405-19.436-6.405-32.92 0-28.067 8.729-46.22 22.24-46.22 5.657 0 10.111 2.807 12.236 7.704zm43.499 20.008c-8.019-1.897-12.089-4.722-12.089-14.951V1.309l-48.716 14.353v1.757l.299-.024c6.72-.543 11.278.386 13.925 2.83 2.072 1.915 3.082 4.853 3.082 8.987v18.66c-4.803-3.067-10.516-4.56-17.448-4.56-14.059 0-26.909 5.92-36.176 16.672-9.66 11.205-14.767 26.518-14.767 44.278-.003 31.72 15.612 53.039 38.851 53.039 13.595 0 24.533-7.449 29.54-20.013v16.865h43.711v-1.746zM424.1 19.819c0-9.904-7.468-17.374-17.375-17.374-9.859 0-17.573 7.632-17.573 17.374s7.721 17.374 17.573 17.374c9.907 0 17.375-7.47 17.375-17.374m11.499 132.546c-8.019-1.897-12.089-4.722-12.089-14.951h-.035V43.635l-43.714 12.551v1.705l.263.024c9.458.842 12.047 4.1 12.047 15.152v81.086h43.751v-1.746zm112.013 0c-8.018-1.897-12.089-4.722-12.089-14.951V43.635l-41.621 12.137v1.71l.246.026c7.733.813 9.967 4.257 9.967 15.36v59.279c-2.578 5.102-7.415 8.131-13.274 8.336-9.503 0-14.736-6.419-14.736-18.073V43.638l-43.714 12.55v1.703l.262.024c9.459.84 12.05 4.097 12.05 15.152v50.17a56.3 56.3 0 0 0 .91 10.444l.787 3.423c3.701 13.262 13.398 20.197 28.59 20.197 12.868 0 24.147-7.966 29.115-20.43v17.311h43.714v-1.747zm169.818 1.788v-1.749l-.213-.05c-8.7-2.006-12.089-5.789-12.089-13.49v-63.79c0-19.89-11.171-31.761-29.883-31.761-13.64 0-25.141 7.882-29.569 20.16-3.517-13.01-13.639-20.16-28.606-20.16-13.146 0-23.449 6.938-27.869 18.657V43.643L545.487 55.68v1.715l.263.024c9.345.829 12.047 4.181 12.047 14.95v81.784h40.787v-1.746l-.215-.053c-6.941-1.631-9.181-4.606-9.181-12.239V66.998c1.836-4.289 5.537-9.37 12.853-9.37 9.086 0 13.692 6.296 13.692 18.697v77.828h40.797v-1.746l-.215-.053c-6.94-1.631-9.18-4.606-9.18-12.239V75.066a42 42 0 0 0-.578-7.26c1.947-4.661 5.86-10.177 13.475-10.177 9.214 0 13.691 6.114 13.691 18.696v77.828z"></path></svg></a><div class="ax h"><div class="ab ay az ba bb q bc bd"><div class="bm" aria-hidden="false" aria-describedby="searchResults" aria-labelledby="searchResults"></div><div class="bn bo ab"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M4.092 11.06a6.95 6.95 0 1 1 13.9 0 6.95 6.95 0 0 1-13.9 0m6.95-8.05a8.05 8.05 0 1 0 5.13 14.26l3.75 3.75a.56.56 0 1 0 .79-.79l-3.73-3.73A8.05 8.05 0 0 0 11.042 3z" clip-rule="evenodd"></path></svg></div><input role="combobox" aria-controls="searchResults" aria-expanded="false" aria-label="search" data-testid="headerSearchInput" tabindex="0" class="ay be bf bg z bh bi bj bk bl" placeholder="Search" value=""/></div></div></div><div class="h k w fg fh"><div class="fi ab"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerWriteButton" rel="noopener follow" href="/m/signin?operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fnew-story&amp;source=---top_nav_layout_nav-----------------------new_post_topnav-----------"><div class="bf b bg z du fj fk ab q fl fm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24" aria-label="Write"><path fill="currentColor" d="M14 4a.5.5 0 0 0 0-1zm7 6a.5.5 0 0 0-1 0zm-7-7H4v1h10zM3 4v16h1V4zm1 17h16v-1H4zm17-1V10h-1v10zm-1 1a1 1 0 0 0 1-1h-1zM3 20a1 1 0 0 0 1 1v-1zM4 3a1 1 0 0 0-1 1h1z"></path><path stroke="currentColor" d="m17.5 4.5-8.458 8.458a.25.25 0 0 0-.06.098l-.824 2.47a.25.25 0 0 0 .316.316l2.47-.823a.25.25 0 0 0 .098-.06L19.5 6.5m-2-2 2.323-2.323a.25.25 0 0 1 .354 0l1.646 1.646a.25.25 0 0 1 0 .354L19.5 6.5m-2-2 2 2"></path></svg><div class="dt l">Write</div></div></a></span></div></div><div class="k j i d"><div class="fi ab"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSearchButton" rel="noopener follow" href="/search?source=---top_nav_layout_nav----------------------------------"><div class="bf b bg z du fj fk ab q fl fm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24" aria-label="Search"><path fill="currentColor" fill-rule="evenodd" d="M4.092 11.06a6.95 6.95 0 1 1 13.9 0 6.95 6.95 0 0 1-13.9 0m6.95-8.05a8.05 8.05 0 1 0 5.13 14.26l3.75 3.75a.56.56 0 1 0 .79-.79l-3.73-3.73A8.05 8.05 0 0 0 11.042 3z" clip-rule="evenodd"></path></svg></div></a></div></div><div class="fi h k j"><div class="ab q"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><button class="bf b dx dy eh dz ea ei eb ec ej ek ee el em eg eo ep eq er es et eu ev ew ex ey ez fa fb fc fd bm fe ff" data-testid="headerSignUpButton">Sign up</button></span></p><div class="ax l"><p class="bf b dx dy dz ea eb ec ed ee ef eg du"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerSignInButton" rel="noopener follow" href="/m/signin?operation=login&amp;redirect=https%3A%2F%2Fmedium.com%2Fflutter-community%2Fmy-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a&amp;source=post_page---top_nav_layout_nav-----------------------global_nav-----------">Sign in</a></span></p></div></div></div><div class="l" aria-hidden="false"><button class="ay fn am ab q ao fo fp fq" aria-label="user options menu" data-testid="headerUserIcon"><div class="l fj"><img alt="" class="l fd by bz ca cx" src="https://miro.medium.com/v2/resize:fill:64:64/1*dmbNkD5D-u45r44go_cf0g.png" width="32" height="32" loading="lazy" role="presentation"/><div class="fr by l bz ca fs n ay ft"></div></div></button></div></div></div><div class="l"><div class="fu fv fw fx fy l"><div class="ab cb"><div class="ci bh fz ga gb gc"></div></div><article><div class="l"><div class="l"><span class="l"></span><section><div><div class="fs gi gj gk gl gm"></div><div class="gn go gp gq gr"><div class="ab cb"><div class="ci bh fz ga gb gc"><div><h1 id="0e43" class="pw-post-title gs gt gu bf gv gw gx gy gz ha hb hc hd he hf hg hh hi hj hk hl hm hn ho hp hq bk" data-testid="storyTitle">My First Step into Unit Testing in Flutter: Simple Explanations</h1></div><div><h2 id="3c65" class="pw-subtitle-paragraph hr gt gu bf b hs ht hu hv hw hx hy hz ia ib ic id ie if ig cq du">Testing used to be a boring side for me.</h2><div><div class="speechify-ignore ab cp"><div class="speechify-ignore bh l"><div class="ih ii ij ik il ab"><div><div class="ab im"><div><div class="bm" aria-hidden="false"><a rel="noopener follow" href="/@surajbhandari5502?source=post_page---byline--64e0c4bc4d1a--------------------------------"><div class="l in io by ip iq"><div class="l fj"><img alt="Surajbhandari" class="l fd by dd de cx" src="https://miro.medium.com/v2/resize:fill:88:88/1*_11O6c-R6RQbcIiJN-OSAA.png" width="44" height="44" loading="lazy" data-testid="authorPhoto"/><div class="ir by l dd de fs n is ft"></div></div></div></a></div></div><div class="it ab fj"><div><div class="bm" aria-hidden="false"><a href="https://medium.com/flutter-community?source=post_page---byline--64e0c4bc4d1a--------------------------------" rel="noopener follow"><div class="l iu iv by ip iw"><div class="l fj"><img alt="Flutter Community" class="l fd by br ix cx" src="https://miro.medium.com/v2/resize:fill:48:48/1*nE4OFcqk2kx2-Lzhey8QKA.png" width="24" height="24" loading="lazy" data-testid="publicationPhoto"/><div class="ir by l br ix fs n is ft"></div></div></div></a></div></div></div></div></div><div class="bn bh l"><div class="ab"><div style="flex:1"><span class="bf b bg z bk"><div class="iy ab q"><div class="ab q iz"><div class="ab q"><div><div class="bm" aria-hidden="false"><p class="bf b ja jb bk"><a class="af ag ah ai aj ak al am an ao ap aq ar jc" data-testid="authorName" rel="noopener follow" href="/@surajbhandari5502?source=post_page---byline--64e0c4bc4d1a--------------------------------">Surajbhandari</a></p></div></div></div><span class="jd je" aria-hidden="true"><span class="bf b bg z du">·</span></span><p class="bf b ja jb du"><span><a class="jf jg ah ai aj ak al am an ao ap aq ar ex jh ji" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fsubscribe%2Fuser%2F2d341a775164&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fflutter-community%2Fmy-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a&amp;user=Surajbhandari&amp;userId=2d341a775164&amp;source=post_page-2d341a775164--byline--64e0c4bc4d1a---------------------post_header-----------">Follow</a></span></p></div></div></span></div></div><div class="l jj"><span class="bf b bg z du"><div class="ab cn jk jl jm"><div class="jn jo ab"><div class="bf b bg z du ab jp"><span class="jq l jj">Published in</span><div><div class="l" aria-hidden="false"><a class="af ag ah ai aj ak al am an ao ap aq ar jc ab q" data-testid="publicationName" href="https://medium.com/flutter-community?source=post_page---byline--64e0c4bc4d1a--------------------------------" rel="noopener follow"><p class="bf b bg z jr js jt ju jv jw jx jy bk">Flutter Community</p></a></div></div></div><div class="h k"><span class="jd je" aria-hidden="true"><span class="bf b bg z du">·</span></span></div></div><span class="bf b bg z du"><div class="ab ae"><span data-testid="storyReadTime">8 min read</span><div class="jz ka l" aria-hidden="true"><span class="l" aria-hidden="true"><span class="bf b bg z du">·</span></span></div><span data-testid="storyPublishDate">Nov 12, 2024</span></div></span></div></span></div></div></div><div class="ab cp kb kc kd ke kf kg kh ki kj kk kl km kn ko kp kq"><div class="h k w fg fh q"><div class="lg l"><div class="ab q lh li"><div class="pw-multi-vote-icon fj jq lj lk ll"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerClapButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fflutter-community%2F64e0c4bc4d1a&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fflutter-community%2Fmy-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a&amp;user=Surajbhandari&amp;userId=2d341a775164&amp;source=---header_actions--64e0c4bc4d1a---------------------clap_footer-----------"><div><div class="bm" aria-hidden="false"><div class="lm ao ln lo lp lq am lr ls lt ll"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l lu lv lw lx ly lz ma"><p class="bf b dv z du"><span class="mb">--</span></p></div></div></div><div><div class="bm" aria-hidden="false"><button class="ao lm mc md ab q fk me mf" aria-label="responses"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="mg"><path d="M18.006 16.803c1.533-1.456 2.234-3.325 2.234-5.321C20.24 7.357 16.709 4 12.191 4S4 7.357 4 11.482c0 4.126 3.674 7.482 8.191 7.482.817 0 1.622-.111 2.393-.327.231.2.48.391.744.559 1.06.693 2.203 1.044 3.399 1.044.224-.008.4-.112.486-.287a.49.49 0 0 0-.042-.518c-.495-.67-.845-1.364-1.04-2.057a4 4 0 0 1-.125-.598zm-3.122 1.055-.067-.223-.315.096a8 8 0 0 1-2.311.338c-4.023 0-7.292-2.955-7.292-6.587 0-3.633 3.269-6.588 7.292-6.588 4.014 0 7.112 2.958 7.112 6.593 0 1.794-.608 3.469-2.027 4.72l-.195.168v.255c0 .056 0 .151.016.295.025.231.081.478.154.733.154.558.398 1.117.722 1.659a5.3 5.3 0 0 1-2.165-.845c-.276-.176-.714-.383-.941-.59z"></path></svg></button></div></div></div><div class="ab q kr ks kt ku kv kw kx ky kz la lb lc ld le lf"><div class="mh k j i d"></div><div class="h k"><div><div class="bm" aria-hidden="false"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="headerBookmarkButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fbookmark%2Fp%2F64e0c4bc4d1a&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fflutter-community%2Fmy-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a&amp;source=---header_actions--64e0c4bc4d1a---------------------bookmark_footer-----------"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="none" viewBox="0 0 25 25" class="du mi" aria-label="Add to list bookmark button"><path fill="currentColor" d="M18 2.5a.5.5 0 0 1 1 0V5h2.5a.5.5 0 0 1 0 1H19v2.5a.5.5 0 1 1-1 0V6h-2.5a.5.5 0 0 1 0-1H18zM7 7a1 1 0 0 1 1-1h3.5a.5.5 0 0 0 0-1H8a2 2 0 0 0-2 2v14a.5.5 0 0 0 .805.396L12.5 17l5.695 4.396A.5.5 0 0 0 19 21v-8.5a.5.5 0 0 0-1 0v7.485l-5.195-4.012a.5.5 0 0 0-.61 0L7 19.985z"></path></svg></a></span></div></div></div><div class="fd mj cn"><div class="l ae"><div class="ab cb"><div class="mk ml mm mn mo mp ci bh"><div class="ab"><div class="bm bh" aria-hidden="false"><div><div class="bm" aria-hidden="false"><button aria-label="Listen" data-testid="audioPlayButton" class="af fk ah ai aj ak al mq an ao ap ex mr ms mf mt mu mv mw mx s my mz na nb nc nd ne u nf ng nh"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M3 12a9 9 0 1 1 18 0 9 9 0 0 1-18 0m9-10C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2m3.376 10.416-4.599 3.066a.5.5 0 0 1-.777-.416V8.934a.5.5 0 0 1 .777-.416l4.599 3.066a.5.5 0 0 1 0 .832" clip-rule="evenodd"></path></svg><div class="j i d"><p class="bf b bg z du">Listen</p></div></button></div></div></div></div></div></div></div></div><div class="bm" aria-hidden="false" aria-describedby="postFooterSocialMenu" aria-labelledby="postFooterSocialMenu"><div><div class="bm" aria-hidden="false"><button aria-controls="postFooterSocialMenu" aria-expanded="false" aria-label="Share Post" data-testid="headerSocialShareButton" class="af fk ah ai aj ak al mq an ao ap ex mr ms mf mt mu mv mw mx s my mz na nb nc nd ne u nf ng nh"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M15.218 4.931a.4.4 0 0 1-.118.132l.012.006a.45.45 0 0 1-.292.074.5.5 0 0 1-.3-.13l-2.02-2.02v7.07c0 .28-.23.5-.5.5s-.5-.22-.5-.5v-7.04l-2 2a.45.45 0 0 1-.57.04h-.02a.4.4 0 0 1-.16-.3.4.4 0 0 1 .1-.32l2.8-2.8a.5.5 0 0 1 .7 0l2.8 2.79a.42.42 0 0 1 .068.498m-.106.138.008.004v-.01zM16 7.063h1.5a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-11c-1.1 0-2-.9-2-2v-10a2 2 0 0 1 2-2H8a.5.5 0 0 1 .35.15.5.5 0 0 1 .15.35.5.5 0 0 1-.15.35.5.5 0 0 1-.35.15H6.4c-.5 0-.9.4-.9.9v10.2a.9.9 0 0 0 .9.9h11.2c.5 0 .9-.4.9-.9v-10.2c0-.5-.4-.9-.9-.9H16a.5.5 0 0 1 0-1" clip-rule="evenodd"></path></svg><div class="j i d"><p class="bf b bg z du">Share</p></div></button></div></div></div></div></div></div></div></div></div><figure class="nl nm nn no np nq ni nj paragraph-image"><div role="button" tabindex="0" class="nr ns fj nt bh nu"><div class="ni nj nk"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*iHGUNxLXc7mKwpqKw5JAOw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*iHGUNxLXc7mKwpqKw5JAOw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*iHGUNxLXc7mKwpqKw5JAOw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*iHGUNxLXc7mKwpqKw5JAOw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*iHGUNxLXc7mKwpqKw5JAOw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*iHGUNxLXc7mKwpqKw5JAOw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*iHGUNxLXc7mKwpqKw5JAOw.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*iHGUNxLXc7mKwpqKw5JAOw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*iHGUNxLXc7mKwpqKw5JAOw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*iHGUNxLXc7mKwpqKw5JAOw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*iHGUNxLXc7mKwpqKw5JAOw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*iHGUNxLXc7mKwpqKw5JAOw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*iHGUNxLXc7mKwpqKw5JAOw.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*iHGUNxLXc7mKwpqKw5JAOw.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh mp nv c" width="700" height="700" loading="eager" role="presentation"/></picture></div></div><figcaption class="nw ff nx ni nj ny nz bf b bg z du">Image by author</figcaption></figure><p id="fcd5" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">I have been involved with Flutter for the past three years. I was busy running a race for a good Flutter developer.</p><p id="7b62" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">One day I heard about Test Driven Development (TDD), which is an approach to writing test cases before actual code is written for an app.</p><p id="3092" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">When I started writing BOOM!! I did not meet my deadline for the feature I needed to implement in my project. Since testing was not mandatory on that project, I left and got busy directly writing the actual code, forgetting about test cases.</p><blockquote class="ow ox oy"><p id="ab15" class="oa ob oz oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Again, after 2 years, I am here, thinking of writing test cases with different energy. FINALLY!!</p></blockquote><figure class="nl nm nn no np nq ni nj paragraph-image"><div class="ni nj pa"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/0*tuIIdg1RChof-AwD.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*tuIIdg1RChof-AwD.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*tuIIdg1RChof-AwD.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*tuIIdg1RChof-AwD.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*tuIIdg1RChof-AwD.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*tuIIdg1RChof-AwD.gif 1100w, https://miro.medium.com/v2/resize:fit:996/format:webp/0*tuIIdg1RChof-AwD.gif 996w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 498px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/0*tuIIdg1RChof-AwD.gif 640w, https://miro.medium.com/v2/resize:fit:720/0*tuIIdg1RChof-AwD.gif 720w, https://miro.medium.com/v2/resize:fit:750/0*tuIIdg1RChof-AwD.gif 750w, https://miro.medium.com/v2/resize:fit:786/0*tuIIdg1RChof-AwD.gif 786w, https://miro.medium.com/v2/resize:fit:828/0*tuIIdg1RChof-AwD.gif 828w, https://miro.medium.com/v2/resize:fit:1100/0*tuIIdg1RChof-AwD.gif 1100w, https://miro.medium.com/v2/resize:fit:996/0*tuIIdg1RChof-AwD.gif 996w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 498px"/><img alt="" class="bh mp nv c" width="498" height="498" loading="lazy" role="presentation"/></picture></div><figcaption class="nw ff nx ni nj ny nz bf b bg z du">Gif Source: <a class="af pb" href="https://tenor.com/" rel="noopener ugc nofollow" target="_blank">tenor</a></figcaption></figure><p id="50f0" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Let me tell you what I found when I explored <em class="oz">how testing in Flutter works in real apps.</em></p><p id="2f05" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">I wanna also inform you that it’s not necessary to connect any device or emulator to run test cases. In this story, I will go with the basic structure of a test case which will test your actual code.</p><p id="a312" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">The test case code is written under the <em class="oz">test </em>Folder (This folder is like the 2nd page of a Google search, very few developers go there 😅).</p><p id="62ff" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">I would like to inform you that we will talk about new <code class="cx pc pd pe pf b">main()</code> method that will act as the root of the testing process.</p><p id="4927" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">The below picture is the basic structure of test cases.</p><figure class="nl nm nn no np nq ni nj paragraph-image"><div class="ni nj pg"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*u4H-RKl35a4NU6E2MduZMw.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*u4H-RKl35a4NU6E2MduZMw.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*u4H-RKl35a4NU6E2MduZMw.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*u4H-RKl35a4NU6E2MduZMw.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*u4H-RKl35a4NU6E2MduZMw.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*u4H-RKl35a4NU6E2MduZMw.png 1100w, https://miro.medium.com/v2/resize:fit:1140/format:webp/1*u4H-RKl35a4NU6E2MduZMw.png 1140w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 570px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*u4H-RKl35a4NU6E2MduZMw.png 640w, https://miro.medium.com/v2/resize:fit:720/1*u4H-RKl35a4NU6E2MduZMw.png 720w, https://miro.medium.com/v2/resize:fit:750/1*u4H-RKl35a4NU6E2MduZMw.png 750w, https://miro.medium.com/v2/resize:fit:786/1*u4H-RKl35a4NU6E2MduZMw.png 786w, https://miro.medium.com/v2/resize:fit:828/1*u4H-RKl35a4NU6E2MduZMw.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*u4H-RKl35a4NU6E2MduZMw.png 1100w, https://miro.medium.com/v2/resize:fit:1140/1*u4H-RKl35a4NU6E2MduZMw.png 1140w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 570px"/><img alt="" class="bh mp nv c" width="570" height="442" loading="lazy" role="presentation"/></picture></div><figcaption class="nw ff nx ni nj ny nz bf b bg z du">Basic structure for writing test code (Image by Author)</figcaption></figure><p id="10dc" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk"><strong class="oc gv">Arrange</strong>, <strong class="oc gv">Act, </strong>and <strong class="oc gv">Assert</strong>, are the 3 blocks of a test method that a developer has to follow.</p><p id="eb13" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk ph"><span class="l pi pj pk bo pl pm pn po pp fj">R</span>emember in the TDD approach we will write test cases first followed by writing actual code. we say it as the <strong class="oc gv">Red-Green-Refactor </strong>cycle<strong class="oc gv">.</strong></p><ul class=""><li id="ef21" class="oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov pq pr ps bk"><strong class="oc gv">Red</strong>: 🛑 It is called red because here your test case will surely fail. It fails because since the test case is written before the actual code so in this step your test case will not find the actual code that is going to be tested.</li><li id="93a3" class="oa ob gu oc b hs pt oe of hv pu oh oi oj pv ol om on pw op oq or px ot ou ov pq pr ps bk"><strong class="oc gv">Green: </strong>💚Here your test case gets passed. This step takes place only after you have written your actual code that needs to be tested. Remember here you will make the test pass with <em class="oz">minimum test code</em>.</li><li id="b2c6" class="oa ob gu oc b hs pt oe of hv pu oh oi oj pv ol om on pw op oq or px ot ou ov pq pr ps bk"><strong class="oc gv">Refactor:</strong>🔧<strong class="oc gv"> </strong>You will improve your test code although test cases are still passing.</li></ul><p id="ffbb" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Let me show you an example to write a unit test for a very simple function.</p><p id="c64c" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Suppose I have a <code class="cx pc pd pe pf b">Counter</code> class somewhere in the lib folder with two methods <code class="cx pc pd pe pf b">increment()</code> and <code class="cx pc pd pe pf b">decrement()</code> .</p><pre class="nl nm nn no np py pf pz bp qa bb bk"><span id="b53e" class="qb qc gu pf b bg qd qe l qf qg">class Counter {<br/><br/> int value=0;<br/><br/><br/>void increment(){<br/><br/> value ++<br/><br/>}<br/><br/>void decrement(){<br/><br/> value --<br/><br/>}<br/><br/>}</span></pre><p id="d121" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Let&#x27;s write a test code for them. I mean to say let&#x27;s go to Google search page no .2 😅 , Just for fun.</p><p id="8e48" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Here we will open a folder called “test” which is just inside your root folder of a project, If you don&#x27;t have create it.</p><p id="7da1" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Inside this folder, I will write a test code for the above methods.</p><pre class="nl nm nn no np py pf pz bp qa bb bk"><span id="df15" class="qb qc gu pf b bg qd qe l qf qg">void main() {<br/> group(&#x27;Counter&#x27;, () {<br/><br/> test(&#x27;initial value should be 0&#x27;, () {<br/><br/> // Arrange<br/> final counter = Counter();<br/><br/> // Act<br/> //[ No action needed as we&#x27;re just checking the initial value].<br/><br/> // Assert<br/> expect(counter.value, 0);<br/> });<br/><br/><br/><br/> test(&#x27;increment should increase value by 1&#x27;, () {<br/><br/> // Arrange<br/> final counter = Counter();<br/><br/> // Act<br/> counter.increment();<br/><br/> // Assert<br/> expect(counter.value, 1);<br/> });<br/><br/><br/> test(&#x27;decrement should decrease value by 1&#x27;, () {<br/><br/> // Arrange<br/> final counter = Counter();<br/><br/> // Act<br/> counter.decrement();<br/><br/> // Assert<br/> expect(counter.value, -1);<br/> });<br/> });<br/>}<br/><br/>///Notes:<br/><br/>///group() : It is the collection of similar test cases which helps to organize tests well.<br/>///test() : Defines a single test with description and cases.<br/></span></pre><p id="6212" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Remember to follow the <strong class="oc gv">Red-Green-Refactor </strong>cycle.</p><p id="22ca" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">If I run the test, It will pass all of them as shown in the image below.</p><figure class="nl nm nn no np nq ni nj paragraph-image"><div role="button" tabindex="0" class="nr ns fj nt bh nu"><div class="ni nj qh"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*cWG4DCata-tk3_PggKZABQ.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*cWG4DCata-tk3_PggKZABQ.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*cWG4DCata-tk3_PggKZABQ.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*cWG4DCata-tk3_PggKZABQ.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*cWG4DCata-tk3_PggKZABQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*cWG4DCata-tk3_PggKZABQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*cWG4DCata-tk3_PggKZABQ.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*cWG4DCata-tk3_PggKZABQ.png 640w, https://miro.medium.com/v2/resize:fit:720/1*cWG4DCata-tk3_PggKZABQ.png 720w, https://miro.medium.com/v2/resize:fit:750/1*cWG4DCata-tk3_PggKZABQ.png 750w, https://miro.medium.com/v2/resize:fit:786/1*cWG4DCata-tk3_PggKZABQ.png 786w, https://miro.medium.com/v2/resize:fit:828/1*cWG4DCata-tk3_PggKZABQ.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*cWG4DCata-tk3_PggKZABQ.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*cWG4DCata-tk3_PggKZABQ.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="Image showing passing test cases in flutter." class="bh mp nv c" width="700" height="145" loading="lazy"/></picture></div></div><figcaption class="nw ff nx ni nj ny nz bf b bg z du">Image showing passing test cases.(Image by Author)</figcaption></figure><blockquote class="ow ox oy"><p id="201c" class="oa ob oz oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Yahoo!! I guess we have completed the first level of testing actual code in flutter.</p></blockquote><p id="810b" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">This is what you need to know for writing basic unit tests in Flutter.</p><p id="5912" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk ph"><span class="l pi pj pk bo pl pm pn po pp fj">N</span>ow let&#x27;s push our leg to another level. Wait !! It&#x27;s easy, just stay with me.</p><blockquote class="ow ox oy"><p id="97b3" class="oa ob oz oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Remember you will not call any external library or any API calls in unit testing.</p></blockquote><p id="e788" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">So, how will I know if my repository is working properly during API calls or if the external library is used properly?</p><figure class="nl nm nn no np nq ni nj paragraph-image"><div class="ni nj qi"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/0*__nnM87gy1opu7N-.gif 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/0*__nnM87gy1opu7N-.gif 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/0*__nnM87gy1opu7N-.gif 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/0*__nnM87gy1opu7N-.gif 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/0*__nnM87gy1opu7N-.gif 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/0*__nnM87gy1opu7N-.gif 1100w, https://miro.medium.com/v2/resize:fit:1280/format:webp/0*__nnM87gy1opu7N-.gif 1280w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 640px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/0*__nnM87gy1opu7N-.gif 640w, https://miro.medium.com/v2/resize:fit:720/0*__nnM87gy1opu7N-.gif 720w, https://miro.medium.com/v2/resize:fit:750/0*__nnM87gy1opu7N-.gif 750w, https://miro.medium.com/v2/resize:fit:786/0*__nnM87gy1opu7N-.gif 786w, https://miro.medium.com/v2/resize:fit:828/0*__nnM87gy1opu7N-.gif 828w, https://miro.medium.com/v2/resize:fit:1100/0*__nnM87gy1opu7N-.gif 1100w, https://miro.medium.com/v2/resize:fit:1280/0*__nnM87gy1opu7N-.gif 1280w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 640px"/><img alt="" class="bh mp nv c" width="640" height="476" loading="lazy" role="presentation"/></picture></div><figcaption class="nw ff nx ni nj ny nz bf b bg z du">Gif Source: <a class="af pb" href="https://tenor.com/" rel="noopener ugc nofollow" target="_blank">tenor</a></figcaption></figure><blockquote class="ow ox oy"><p id="06c7" class="oa ob oz oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Here comes <strong class="oc gv">Mocking !</strong></p></blockquote><p id="0c90" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Yeah, we can mock these with their fake objects.</p><p id="b78c" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk"><code class="cx pc pd pe pf b">mockito</code> package is commonly used for creating mocks in Flutter. You can get it from <a class="af pb" href="https://pub.dev/packages/mockito" rel="noopener ugc nofollow" target="_blank">here</a>. You will also need <code class="cx pc pd pe pf b">build_runner</code> package to generate mocks automatically.</p><p id="5972" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">I wanna show you how I did a mocking of an API call in my project. I am willing to show you the API call to log in to the app.</p><p id="6c6c" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Please see some code that I have written for my project.</p><p id="0821" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk"><em class="oz">Note: I am using </em><code class="cx pc pd pe pf b"><a class="af pb" href="https://pub.dev/packages/flutter_riverpod" rel="noopener ugc nofollow" target="_blank"><em class="oz">flutter_riverpod </em></a></code><em class="oz">as a state management technique in my app.</em></p><p id="8ee0" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">This is inside the Controller Folder, where I have the following method which will call API from the Repository folder (I will show you Repo later):</p><pre class="nl nm nn no np py pf pz bp qa bb bk"><span id="15db" class="qb qc gu pf b bg qd qe l qf qg">class AuthController extends StateNotifier&lt;BaseState&lt;dynamic&gt;&gt; {<br/> AuthController(this._read) : super(const BaseState&lt;void&gt;.initial());<br/><br/> final StateNotifierProviderRef&lt;dynamic, dynamic&gt; _read;<br/><br/> IAuthRepository get _repo =&gt; _read.read(authRepository);<br/><br/><br/><br/>Future&lt;void&gt; loginUser({<br/> required LoginRequest loginRequest,<br/> }) async {<br/> state = const BaseState.loading();<br/> final response = await _repo.login(loginRequest: loginRequest);<br/> state = response.fold(<br/> (loginSuccess) {<br/> return BaseState.success(data: loginSuccess);<br/> },<br/> (error) {<br/> return BaseState.error(error);<br/> },<br/> );<br/> }<br/><br/>}</span></pre><p id="8be6" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Basically above code shows that <code class="cx pc pd pe pf b">loginUser</code> methods is calling another method from repository to call an API.</p><p id="c1c1" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Let me show you how you can write unit tests for the above <code class="cx pc pd pe pf b">loginUser</code> method.</p><p id="8e08" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Let me show you how my Ripo looks :</p><pre class="nl nm nn no np py pf pz bp qa bb bk"><span id="80d6" class="qb qc gu pf b bg qd qe l qf qg">abstract class IAuthRepository {<br/> Future&lt;Either&lt;LoginResponse, Failure&gt;&gt; login({<br/> required LoginRequest loginRequest,<br/> });<br/><br/><br/> @override<br/> Future&lt;Either&lt;LoginResponse, Failure&gt;&gt; login({<br/> required LoginRequest loginRequest,<br/> }) async {<br/> try {<br/> final response = await _apiHelper.post(<br/> endPoint: ApiEndpoints.loginEndpoint,<br/> data: loginRequest.toJson(),<br/> );<br/><br/> final data =<br/> LoginResponse.fromJson(response.data as Map&lt;String, dynamic&gt;);<br/> if (data.isSuccess) {<br/> return Left(data);<br/> } else {<br/> return Right(Failure.fromException(&quot;Something went wrong&quot;));<br/> }<br/> } catch (e) {<br/> return Right(Failure.fromException(e));<br/> }<br/> }<br/></span></pre><p id="196f" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">The above method is called a <code class="cx pc pd pe pf b">post</code> method to call login API. Here if Login fails it returns <code class="cx pc pd pe pf b">Failure</code> in the Right of <code class="cx pc pd pe pf b">Either</code> else <code class="cx pc pd pe pf b">LoginResponse</code> is returned in <code class="cx pc pd pe pf b">Left</code> of <code class="cx pc pd pe pf b">Either.</code></p><p id="d342" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">Now finally dive into the test folder. I will explain the code below. Here, I am trying to comment on each line of code so that none of the developers will get into trouble while reading.</p><pre class="nl nm nn no np py pf pz bp qa bb bk"><span id="da4f" class="qb qc gu pf b bg qd qe l qf qg">// Import the necessary packages and classes<br/>// Generate a Mock class for IAuthRepository<br/>@GenerateMocks([IAuthRepository])<br/>void main() {<br/> // Declare variables for test setup<br/> late ProviderContainer container; // Used to manage dependencies and overrides during tests<br/> late MockIAuthRepository mockAuthRepository; // Mock object for IAuthRepository to simulate login behavior<br/> late LoginRequest loginRequest; // Object to represent the login request data<br/> late LoginResponse loginSuccessResponse; // Object to represent a successful login response<br/> late Failure loginFailureResponse; // Object to represent a failed login response<br/><br/> // setUp() function runs before each test, initializing necessary objects<br/> setUp(() {<br/> // Initialize the mock repository and login request details<br/> mockAuthRepository = MockIAuthRepository();<br/> loginRequest = LoginRequest(<br/> username: &#x27;testUser&#x27;,<br/> password: &#x27;password123&#x27;,<br/> );<br/><br/> // Define a successful login response for the mock repository to return<br/> loginSuccessResponse = LoginResponse(<br/> accessToken: &quot;accessToken&quot;,<br/> isSuccess: true,<br/> configuration: [],<br/> userName: &quot;userName&quot;);<br/><br/> // Define a failure response<br/> loginFailureResponse = Failure(&#x27;got issue&#x27;, FailureType.exception);<br/><br/> // Create a ProviderContainer to manage providers during tests<br/> container = ProviderContainer(<br/> overrides: [<br/> // Override the authRepository provider with our mock repository<br/> authRepository.overrideWithValue(mockAuthRepository),<br/> ],<br/> );<br/> });<br/><br/> // tearDown() function runs after each test, cleaning up resources<br/> tearDown(() {<br/> container.dispose(); // Dispose of the container to free up resources<br/> });<br/><br/> // Group related tests for the loginUser function<br/> group(&#x27;loginUser&#x27;, () {<br/> // Test the success scenario of loginUser<br/> test(&#x27;emits loading and success states when login is successful&#x27;, () async {<br/> // Arrange: Set up the mockAuthRepository to return a successful login response<br/> when(mockAuthRepository.login(loginRequest: loginRequest))<br/> .thenAnswer((_) async =&gt; Left(loginSuccessResponse));<br/><br/> // Act: Retrieve the authController from the provider container<br/> final authController = container.read(loginController.notifier);<br/><br/> // Assert: Verify initial state is `initial`<br/> expect(authController.state, const BaseState&lt;void&gt;.initial());<br/><br/> // Act: Trigger the loginUser function and verify loading state<br/> final future = authController.loginUser(loginRequest: loginRequest);<br/> expect(authController.state, const BaseState.loading());<br/><br/> // Wait for the future to complete<br/> await future;<br/> print(&#x27;result: ${authController.state}&#x27;);<br/><br/> // Assert: Verify the final state is success with the expected login response data<br/> expect(authController.state,<br/> BaseState&lt;dynamic&gt;.success(data: loginSuccessResponse));<br/> });<br/> });<br/>}</span></pre><p id="c363" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">This is how my output is seen in the terminal after running the test.</p><figure class="nl nm nn no np nq ni nj paragraph-image"><div role="button" tabindex="0" class="nr ns fj nt bh nu"><div class="ni nj qj"><picture><source srcSet="https://miro.medium.com/v2/resize:fit:640/format:webp/1*lulA1ey1JY1cBIpR4bSS9g.png 640w, https://miro.medium.com/v2/resize:fit:720/format:webp/1*lulA1ey1JY1cBIpR4bSS9g.png 720w, https://miro.medium.com/v2/resize:fit:750/format:webp/1*lulA1ey1JY1cBIpR4bSS9g.png 750w, https://miro.medium.com/v2/resize:fit:786/format:webp/1*lulA1ey1JY1cBIpR4bSS9g.png 786w, https://miro.medium.com/v2/resize:fit:828/format:webp/1*lulA1ey1JY1cBIpR4bSS9g.png 828w, https://miro.medium.com/v2/resize:fit:1100/format:webp/1*lulA1ey1JY1cBIpR4bSS9g.png 1100w, https://miro.medium.com/v2/resize:fit:1400/format:webp/1*lulA1ey1JY1cBIpR4bSS9g.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px" type="image/webp"/><source data-testid="og" srcSet="https://miro.medium.com/v2/resize:fit:640/1*lulA1ey1JY1cBIpR4bSS9g.png 640w, https://miro.medium.com/v2/resize:fit:720/1*lulA1ey1JY1cBIpR4bSS9g.png 720w, https://miro.medium.com/v2/resize:fit:750/1*lulA1ey1JY1cBIpR4bSS9g.png 750w, https://miro.medium.com/v2/resize:fit:786/1*lulA1ey1JY1cBIpR4bSS9g.png 786w, https://miro.medium.com/v2/resize:fit:828/1*lulA1ey1JY1cBIpR4bSS9g.png 828w, https://miro.medium.com/v2/resize:fit:1100/1*lulA1ey1JY1cBIpR4bSS9g.png 1100w, https://miro.medium.com/v2/resize:fit:1400/1*lulA1ey1JY1cBIpR4bSS9g.png 1400w" sizes="(min-resolution: 4dppx) and (max-width: 700px) 50vw, (-webkit-min-device-pixel-ratio: 4) and (max-width: 700px) 50vw, (min-resolution: 3dppx) and (max-width: 700px) 67vw, (-webkit-min-device-pixel-ratio: 3) and (max-width: 700px) 65vw, (min-resolution: 2.5dppx) and (max-width: 700px) 80vw, (-webkit-min-device-pixel-ratio: 2.5) and (max-width: 700px) 80vw, (min-resolution: 2dppx) and (max-width: 700px) 100vw, (-webkit-min-device-pixel-ratio: 2) and (max-width: 700px) 100vw, 700px"/><img alt="" class="bh mp nv c" width="700" height="334" loading="lazy" role="presentation"/></picture></div></div><figcaption class="nw ff nx ni nj ny nz bf b bg z du">Image to show a test is passed successfully(Image by Author)</figcaption></figure><h2 id="4437" class="qk qc gu bf ql qm qn dy qo qp qq ea qr oj qs qt qu on qv qw qx or qy qz ra rb bk">Code Explanation</h2><ol class=""><li id="df2b" class="oa ob gu oc b hs rc oe of hv rd oh oi oj re ol om on rf op oq or rg ot ou ov rh pr ps bk"><strong class="oc gv">Setup and Mocking:</strong></li></ol><ul class=""><li id="d5e7" class="oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov pq pr ps bk"><code class="cx pc pd pe pf b">mockito</code>’s <code class="cx pc pd pe pf b">@GenerateMocks</code>annotation is an instruction to generate a mock class for the <code class="cx pc pd pe pf b">IAuthRepository </code>. This is a management tool that allows a mock class to successfully copy the behavior of the original class.</li><li id="8b87" class="oa ob gu oc b hs pt oe of hv pu oh oi oj pv ol om on pw op oq or px ot ou ov pq pr ps bk">In the <code class="cx pc pd pe pf b">setUp </code>function, the login request, the successful login response, and the failure response are initialized. <br/>We instantiate a <code class="cx pc pd pe pf b">ProviderContainer</code>that handles the dependencies. In this case, we use a mock version to override <code class="cx pc pd pe pf b">authRepository</code>. In this case, it makes it possible to control the operations that authenticate are subjected to the tests.</li></ul><p id="5809" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">2. <strong class="oc gv">Test Case for </strong><code class="cx pc pd pe pf b"><strong class="oc gv">loginUser</strong></code>:</p><ul class=""><li id="10ab" class="oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov pq pr ps bk">The test that <code class="cx pc pd pe pf b">&quot;emits loading and success states when login is successful&quot;</code>is to check whether the <code class="cx pc pd pe pf b">loginUser</code>method when the operation is over with the successful login.</li><li id="e378" class="oa ob gu oc b hs pt oe of hv pu oh oi oj pv ol om on pw op oq or px ot ou ov pq pr ps bk"><strong class="oc gv">Arrange</strong>: It covers the situation when <code class="cx pc pd pe pf b">mockAuthRepository.login()</code> should return a login response (with success).</li><li id="80b7" class="oa ob gu oc b hs pt oe of hv pu oh oi oj pv ol om on pw op oq or px ot ou ov pq pr ps bk"><strong class="oc gv">Act</strong>: It brings in the <code class="cx pc pd pe pf b">authController</code>and calls <code class="cx pc pd pe pf b">loginUser(),</code> . Before awaiting the result, the <code class="cx pc pd pe pf b">authController</code>state is inspected to make sure that it goes from the <code class="cx pc pd pe pf b">initial</code>to <code class="cx pc pd pe pf b">loading</code>stages.</li><li id="5e1a" class="oa ob gu oc b hs pt oe of hv pu oh oi oj pv ol om on pw op oq or px ot ou ov pq pr ps bk"><strong class="oc gv">Assert:</strong> After the login is completed, check that the state has been changed to a successful state with the appropriate data.</li></ul><h1 id="28cc" class="ri qc gu bf ql rj rk hu qo rl rm hx qr rn ro rp rq rr rs rt ru rv rw rx ry rz bk">Final words</h1><p id="384f" class="pw-post-body-paragraph oa ob gu oc b hs rc oe of hv rd oh oi oj re ol om on rf op oq or rg ot ou ov gn bk">This is what I have learned till now, So If you have any questions or feedback please do comment.</p><p id="f724" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk">I request you to check this article regularly because I am planning to add more things here in the future to make it better for you and a lot easier to understand what is happening. For now, please do Clap! and I am signing off for today. Ta! Ta! 👋🏻👋🏻👋🏻</p><h2 id="927b" class="qk qc gu bf ql qm qn dy qo qp qq ea qr oj qs qt qu on qv qw qx or qy qz ra rb bk">(☞ ͡° ͜ʖ ͡°)☞ Please follow me for further updates on Flutter!</h2><p id="fba6" class="pw-post-body-paragraph oa ob gu oc b hs rc oe of hv rd oh oi oj re ol om on rf op oq or rg ot ou ov gn bk"><a class="af pb" href="http://buymeacoffee.com/surajbhand" rel="noopener ugc nofollow" target="_blank">Buy me a coffee</a> ☕️</p><p id="7c34" class="pw-post-body-paragraph oa ob gu oc b hs od oe of hv og oh oi oj ok ol om on oo op oq or os ot ou ov gn bk"><a class="af pb" href="https://surajbhandari.info/" rel="noopener ugc nofollow" target="_blank">For more on Flutter Framework please check out here.</a></p></div></div></div></div></section></div></div></article></div><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="sa sb ab jm"><div class="sc ab"><a class="sd ay am ao" rel="noopener follow" href="/tag/programming?source=post_page-----64e0c4bc4d1a--------------------------------"><div class="se fj cx sf ge sg sh bf b bg z bk si">Programming</div></a></div><div class="sc ab"><a class="sd ay am ao" rel="noopener follow" href="/tag/technology?source=post_page-----64e0c4bc4d1a--------------------------------"><div class="se fj cx sf ge sg sh bf b bg z bk si">Technology</div></a></div><div class="sc ab"><a class="sd ay am ao" rel="noopener follow" href="/tag/software-development?source=post_page-----64e0c4bc4d1a--------------------------------"><div class="se fj cx sf ge sg sh bf b bg z bk si">Software Development</div></a></div><div class="sc ab"><a class="sd ay am ao" rel="noopener follow" href="/tag/flutter?source=post_page-----64e0c4bc4d1a--------------------------------"><div class="se fj cx sf ge sg sh bf b bg z bk si">Flutter</div></a></div><div class="sc ab"><a class="sd ay am ao" rel="noopener follow" href="/tag/flutter-app-development?source=post_page-----64e0c4bc4d1a--------------------------------"><div class="se fj cx sf ge sg sh bf b bg z bk si">Flutter App Development</div></a></div></div></div></div><div class="l"></div><footer class="sj sk sl sm sn so sp sq sr ab q ss iw c"><div class="l ae"><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="ab cp st"><div class="ab q lh"><div class="su l"><span class="l sv sw sx e d"><div class="ab q lh li"><div class="pw-multi-vote-icon fj jq lj lk ll"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerClapButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fflutter-community%2F64e0c4bc4d1a&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fflutter-community%2Fmy-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a&amp;user=Surajbhandari&amp;userId=2d341a775164&amp;source=---footer_actions--64e0c4bc4d1a---------------------clap_footer-----------"><div><div class="bm" aria-hidden="false"><div class="lm ao ln lo lp lq am lr ls lt ll"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l lu lv lw lx ly lz ma"><p class="bf b dv z du"><span class="mb">--</span></p></div></div></span><span class="l h g f sy sz"><div class="ab q lh li"><div class="pw-multi-vote-icon fj jq lj lk ll"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerClapButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fvote%2Fflutter-community%2F64e0c4bc4d1a&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fflutter-community%2Fmy-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a&amp;user=Surajbhandari&amp;userId=2d341a775164&amp;source=---footer_actions--64e0c4bc4d1a---------------------clap_footer-----------"><div><div class="bm" aria-hidden="false"><div class="lm ao ln lo lp lq am lr ls lt ll"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" aria-label="clap"><path fill-rule="evenodd" d="M11.37.828 12 3.282l.63-2.454zM13.916 3.953l1.523-2.112-1.184-.39zM8.589 1.84l1.522 2.112-.337-2.501zM18.523 18.92c-.86.86-1.75 1.246-2.62 1.33a6 6 0 0 0 .407-.372c2.388-2.389 2.86-4.951 1.399-7.623l-.912-1.603-.79-1.672c-.26-.56-.194-.98.203-1.288a.7.7 0 0 1 .546-.132c.283.046.546.231.728.5l2.363 4.157c.976 1.624 1.141 4.237-1.324 6.702m-10.999-.438L3.37 14.328a.828.828 0 0 1 .585-1.408.83.83 0 0 1 .585.242l2.158 2.157a.365.365 0 0 0 .516-.516l-2.157-2.158-1.449-1.449a.826.826 0 0 1 1.167-1.17l3.438 3.44a.363.363 0 0 0 .516 0 .364.364 0 0 0 0-.516L5.293 9.513l-.97-.97a.826.826 0 0 1 0-1.166.84.84 0 0 1 1.167 0l.97.968 3.437 3.436a.36.36 0 0 0 .517 0 .366.366 0 0 0 0-.516L6.977 7.83a.82.82 0 0 1-.241-.584.82.82 0 0 1 .824-.826c.219 0 .43.087.584.242l5.787 5.787a.366.366 0 0 0 .587-.415l-1.117-2.363c-.26-.56-.194-.98.204-1.289a.7.7 0 0 1 .546-.132c.283.046.545.232.727.501l2.193 3.86c1.302 2.38.883 4.59-1.277 6.75-1.156 1.156-2.602 1.627-4.19 1.367-1.418-.236-2.866-1.033-4.079-2.246M10.75 5.971l2.12 2.12c-.41.502-.465 1.17-.128 1.89l.22.465-3.523-3.523a.8.8 0 0 1-.097-.368c0-.22.086-.428.241-.584a.847.847 0 0 1 1.167 0m7.355 1.705c-.31-.461-.746-.758-1.23-.837a1.44 1.44 0 0 0-1.11.275c-.312.24-.505.543-.59.881a1.74 1.74 0 0 0-.906-.465 1.47 1.47 0 0 0-.82.106l-2.182-2.182a1.56 1.56 0 0 0-2.2 0 1.54 1.54 0 0 0-.396.701 1.56 1.56 0 0 0-2.21-.01 1.55 1.55 0 0 0-.416.753c-.624-.624-1.649-.624-2.237-.037a1.557 1.557 0 0 0 0 2.2c-.239.1-.501.238-.715.453a1.56 1.56 0 0 0 0 2.2l.516.515a1.556 1.556 0 0 0-.753 2.615L7.01 19c1.32 1.319 2.909 2.189 4.475 2.449q.482.08.971.08c.85 0 1.653-.198 2.393-.579.231.033.46.054.686.054 1.266 0 2.457-.52 3.505-1.567 2.763-2.763 2.552-5.734 1.439-7.586z" clip-rule="evenodd"></path></svg></div></div></div></a></span></div><div class="pw-multi-vote-count l lu lv lw lx ly lz ma"><p class="bf b dv z du"><span class="mb">--</span></p></div></div></span></div><div class="bq ab"><div><div class="bm" aria-hidden="false"><button class="ao lm mc md ab q fk me mf" aria-label="responses"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="mg"><path d="M18.006 16.803c1.533-1.456 2.234-3.325 2.234-5.321C20.24 7.357 16.709 4 12.191 4S4 7.357 4 11.482c0 4.126 3.674 7.482 8.191 7.482.817 0 1.622-.111 2.393-.327.231.2.48.391.744.559 1.06.693 2.203 1.044 3.399 1.044.224-.008.4-.112.486-.287a.49.49 0 0 0-.042-.518c-.495-.67-.845-1.364-1.04-2.057a4 4 0 0 1-.125-.598zm-3.122 1.055-.067-.223-.315.096a8 8 0 0 1-2.311.338c-4.023 0-7.292-2.955-7.292-6.587 0-3.633 3.269-6.588 7.292-6.588 4.014 0 7.112 2.958 7.112 6.593 0 1.794-.608 3.469-2.027 4.72l-.195.168v.255c0 .056 0 .151.016.295.025.231.081.478.154.733.154.558.398 1.117.722 1.659a5.3 5.3 0 0 1-2.165-.845c-.276-.176-.714-.383-.941-.59z"></path></svg></button></div></div></div></div><div class="ab q"><div class="ta l jj"><div><div class="bm" aria-hidden="false"><span><a class="af ag ah ai aj ak al am an ao ap aq ar as at" data-testid="footerBookmarkButton" rel="noopener follow" href="/m/signin?actionUrl=https%3A%2F%2Fmedium.com%2F_%2Fbookmark%2Fp%2F64e0c4bc4d1a&amp;operation=register&amp;redirect=https%3A%2F%2Fmedium.com%2Fflutter-community%2Fmy-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a&amp;source=---footer_actions--64e0c4bc4d1a---------------------bookmark_footer-----------"><svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="none" viewBox="0 0 25 25" class="du mi" aria-label="Add to list bookmark button"><path fill="currentColor" d="M18 2.5a.5.5 0 0 1 1 0V5h2.5a.5.5 0 0 1 0 1H19v2.5a.5.5 0 1 1-1 0V6h-2.5a.5.5 0 0 1 0-1H18zM7 7a1 1 0 0 1 1-1h3.5a.5.5 0 0 0 0-1H8a2 2 0 0 0-2 2v14a.5.5 0 0 0 .805.396L12.5 17l5.695 4.396A.5.5 0 0 0 19 21v-8.5a.5.5 0 0 0-1 0v7.485l-5.195-4.012a.5.5 0 0 0-.61 0L7 19.985z"></path></svg></a></span></div></div></div><div class="ta l jj"><div class="bm" aria-hidden="false" aria-describedby="postFooterSocialMenu" aria-labelledby="postFooterSocialMenu"><div><div class="bm" aria-hidden="false"><button aria-controls="postFooterSocialMenu" aria-expanded="false" aria-label="Share Post" data-testid="footerSocialShareButton" class="af fk ah ai aj ak al mq an ao ap ex mr ms mf mt"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M15.218 4.931a.4.4 0 0 1-.118.132l.012.006a.45.45 0 0 1-.292.074.5.5 0 0 1-.3-.13l-2.02-2.02v7.07c0 .28-.23.5-.5.5s-.5-.22-.5-.5v-7.04l-2 2a.45.45 0 0 1-.57.04h-.02a.4.4 0 0 1-.16-.3.4.4 0 0 1 .1-.32l2.8-2.8a.5.5 0 0 1 .7 0l2.8 2.79a.42.42 0 0 1 .068.498m-.106.138.008.004v-.01zM16 7.063h1.5a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-11c-1.1 0-2-.9-2-2v-10a2 2 0 0 1 2-2H8a.5.5 0 0 1 .35.15.5.5 0 0 1 .15.35.5.5 0 0 1-.15.35.5.5 0 0 1-.35.15H6.4c-.5 0-.9.4-.9.9v10.2a.9.9 0 0 0 .9.9h11.2c.5 0 .9-.4.9-.9v-10.2c0-.5-.4-.9-.9-.9H16a.5.5 0 0 1 0-1" clip-rule="evenodd"></path></svg></button></div></div></div></div></div></div></div></div></div></footer><div class="tb tc td te tf l bx"><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="tg l"><div class="ab th ti tj jl jk"><div class="tk tl tm tn to tp tq tr ts tt ab cp"><div class="h k"><a href="https://medium.com/flutter-community?source=post_page---post_publication_info--64e0c4bc4d1a--------------------------------" rel="noopener follow"><div class="fj ab"><img alt="Flutter Community" class="tu in io cx" src="https://miro.medium.com/v2/resize:fill:96:96/1*nE4OFcqk2kx2-Lzhey8QKA.png" width="48" height="48" loading="lazy"/><div class="tu l io in fs n fr tv"></div></div></a></div><div class="j i d"><a href="https://medium.com/flutter-community?source=post_page---post_publication_info--64e0c4bc4d1a--------------------------------" rel="noopener follow"><div class="fj ab"><img alt="Flutter Community" class="tu tx tw cx" src="https://miro.medium.com/v2/resize:fill:128:128/1*nE4OFcqk2kx2-Lzhey8QKA.png" width="64" height="64" loading="lazy"/><div class="tu l tw tx fs n fr tv"></div></div></a></div><div class="j i d ty jj"><div class="ab"></div></div></div><div class="ab co tz"><div class="ua ub uc ud ue l"><a class="af ag ah aj ak al am an ao ap aq ar as at ab q" href="https://medium.com/flutter-community?source=post_page---post_publication_info--64e0c4bc4d1a--------------------------------" rel="noopener follow"><h2 class="pw-author-name bf ug uh ui uj uk ul um oj qt qu on qw qx or qz ra bk"><span class="gn uf">Published in <!-- -->Flutter Community</span></h2></a><div class="sc ab im"><div class="l jj"><span class="pw-follower-count bf b bg z du"><a class="af ag ah ai aj ak al am an ao ap aq ar jc" rel="noopener follow" href="/flutter-community/followers?source=post_page---post_publication_info--64e0c4bc4d1a--------------------------------">67K Followers</a></span></div><div class="bf b bg z du ab jp"><span class="jd l" aria-hidden="true"><span class="bf b bg z du">·</span></span><a class="af ag ah ai aj ak al am an ao ap aq ar jc" rel="noopener follow" href="/flutter-community/my-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a?source=post_page---post_publication_info--64e0c4bc4d1a--------------------------------">Last published <span>Nov 12, 2024</span></a></div></div><div class="un l"><p class="bf b bg z bk"><span class="gn">Articles and Stories from the Flutter Community</span></p></div></div></div><div class="h k"><div class="ab"></div></div></div></div><div class="ab th ti tj jl jk"><div class="tk tl tm tn to tp tq tr ts tt ab cp"><div class="h k"><a tabindex="0" rel="noopener follow" href="/@surajbhandari5502?source=post_page---post_author_info--64e0c4bc4d1a--------------------------------"><div class="l fj"><img alt="Surajbhandari" class="l fd by io in cx" src="https://miro.medium.com/v2/resize:fill:96:96/1*_11O6c-R6RQbcIiJN-OSAA.png" width="48" height="48" loading="lazy"/><div class="fr by l io in fs n ay tv"></div></div></a></div><div class="j i d"><a tabindex="0" rel="noopener follow" href="/@surajbhandari5502?source=post_page---post_author_info--64e0c4bc4d1a--------------------------------"><div class="l fj"><img alt="Surajbhandari" class="l fd by tw tx cx" src="https://miro.medium.com/v2/resize:fill:128:128/1*_11O6c-R6RQbcIiJN-OSAA.png" width="64" height="64" loading="lazy"/><div class="fr by l tw tx fs n ay tv"></div></div></a></div><div class="j i d ty jj"><div class="ab"><span><button class="bf b bg z uo se up uq ur us ut ev ew uu uv uw fa fb fc fd bm fe ff">Follow</button></span></div></div></div><div class="ab co tz"><div class="ua ub uc ud ue l"><a class="af ag ah aj ak al am an ao ap aq ar as at ab q" rel="noopener follow" href="/@surajbhandari5502?source=post_page---post_author_info--64e0c4bc4d1a--------------------------------"><h2 class="pw-author-name bf ug uh ui uj uk ul um oj qt qu on qw qx or qz ra bk"><span class="gn uf">Written by <!-- -->Surajbhandari</span></h2></a><div class="sc ab im"><div class="l jj"><span class="pw-follower-count bf b bg z du"><a class="af ag ah ai aj ak al am an ao ap aq ar jc" rel="noopener follow" href="/@surajbhandari5502/followers?source=post_page---post_author_info--64e0c4bc4d1a--------------------------------">113 Followers</a></span></div><div class="bf b bg z du ab jp"><span class="jd l" aria-hidden="true"><span class="bf b bg z du">·</span></span><a class="af ag ah ai aj ak al am an ao ap aq ar jc" rel="noopener follow" href="/@surajbhandari5502/following?source=post_page---post_author_info--64e0c4bc4d1a--------------------------------">1.4K Following</a></div></div><div class="un l"><p class="bf b bg z bk"><span class="gn">🖥️ Flutter Developer 🛠️ | 💵 Financial Explorer 📈</span></p></div></div></div><div class="h k"><div class="ab"><span><button class="bf b bg z uo se up uq ur us ut ev ew uu uv uw fa fb fc fd bm fe ff">Follow</button></span></div></div></div><div class="ux bh uy uz"></div></div></div><div class="h k j"><div class="ux bh uy va"></div><div class="ab cb"><div class="ci bh fz ga gb gc"><div class="vb ab lh jm"><div class="vc vd l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://help.medium.com/hc/en-us?source=post_page-----64e0c4bc4d1a--------------------------------" rel="noopener follow"><p class="bf b dv z du">Help</p></a></div><div class="vc vd l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://medium.statuspage.io/?source=post_page-----64e0c4bc4d1a--------------------------------" rel="noopener follow"><p class="bf b dv z du">Status</p></a></div><div class="vc vd l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" rel="noopener follow" href="/about?autoplay=1&amp;source=post_page-----64e0c4bc4d1a--------------------------------"><p class="bf b dv z du">About</p></a></div><div class="vc vd l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" rel="noopener follow" href="/jobs-at-medium/work-at-medium-959d1a85284e?source=post_page-----64e0c4bc4d1a--------------------------------"><p class="bf b dv z du">Careers</p></a></div><div class="vc vd l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="pressinquiries@medium.com?source=post_page-----64e0c4bc4d1a--------------------------------" rel="noopener follow"><p class="bf b dv z du">Press</p></a></div><div class="vc vd l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://blog.medium.com/?source=post_page-----64e0c4bc4d1a--------------------------------" rel="noopener follow"><p class="bf b dv z du">Blog</p></a></div><div class="vc vd l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://policy.medium.com/medium-privacy-policy-f03bf92035c9?source=post_page-----64e0c4bc4d1a--------------------------------" rel="noopener follow"><p class="bf b dv z du">Privacy</p></a></div><div class="vc vd l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://policy.medium.com/medium-terms-of-service-9db0094a1e0f?source=post_page-----64e0c4bc4d1a--------------------------------" rel="noopener follow"><p class="bf b dv z du">Terms</p></a></div><div class="vc vd l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" href="https://speechify.com/medium?source=post_page-----64e0c4bc4d1a--------------------------------" rel="noopener follow"><p class="bf b dv z du">Text to speech</p></a></div><div class="vc l"><a class="af ag ah ai aj ak al am an ao ap aq ar as at" rel="noopener follow" href="/business?source=post_page-----64e0c4bc4d1a--------------------------------"><p class="bf b dv z du">Teams</p></a></div></div></div></div></div></div></div></div></div></div><script>window.__BUILD_ID__="main-20241125-190609-795bd7e319"</script><script>window.__GRAPHQL_URI__ = "https://medium.com/_/graphql"</script><script>window.__PRELOADED_STATE__ = {"algolia":{"queries":{}},"cache":{"experimentGroupSet":true,"reason":"","group":"enabled","tags":["group-edgeCachePosts","post-64e0c4bc4d1a","user-2d341a775164","collection-86fb29d7cc6a"],"serverVariantState":"44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a","middlewareEnabled":true,"cacheStatus":"DYNAMIC","shouldUseCache":true,"vary":[],"lohpSummerUpsellEnabled":false,"publicationHierarchyEnabledWeb":false,"postBottomResponsesEnabled":false},"client":{"hydrated":false,"isUs":false,"isNativeMedium":false,"isSafariMobile":true,"isSafari":true,"isFirefox":false,"routingEntity":{"type":"DEFAULT","explicit":false},"viewerIsBot":false},"debug":{"requestId":"6fe25df1-2ad4-4f22-bd1b-67ba3b8a400f","hybridDevServices":[],"originalSpanCarrier":{"traceparent":"00-2e3f16a3ff43b3f29e6600b98b396430-652d5924f5e8ec61-01"}},"multiVote":{"clapsPerPost":{}},"navigation":{"branch":{"show":null,"hasRendered":null,"blockedByCTA":false},"hideGoogleOneTap":false,"hasRenderedAlternateUserBanner":null,"currentLocation":"https:\u002F\u002Fmedium.com\u002Fflutter-community\u002Fmy-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a","host":"medium.com","hostname":"medium.com","referrer":"","hasSetReferrer":false,"susiModal":{"step":null,"operation":"register"},"postRead":false,"partnerProgram":{"selectedCountryCode":null},"queryString":"","currentHash":""},"config":{"nodeEnv":"production","version":"main-20241125-190609-795bd7e319","target":"production","productName":"Medium","publicUrl":"https:\u002F\u002Fcdn-client.medium.com\u002Flite","authDomain":"medium.com","authGoogleClientId":"216296035834-k1k6qe060s2tp2a2jam4ljdcms00sttg.apps.googleusercontent.com","favicon":"production","glyphUrl":"https:\u002F\u002Fglyph.medium.com","branchKey":"key_live_ofxXr2qTrrU9NqURK8ZwEhknBxiI6KBm","algolia":{"appId":"MQ57UUUQZ2","apiKeySearch":"394474ced050e3911ae2249ecc774921","indexPrefix":"medium_","host":"-dsn.algolia.net"},"recaptchaKey":"6Lfc37IUAAAAAKGGtC6rLS13R1Hrw_BqADfS1LRk","recaptcha3Key":"6Lf8R9wUAAAAABMI_85Wb8melS7Zj6ziuf99Yot5","recaptchaEnterpriseKeyId":"6Le-uGgpAAAAAPprRaokM8AKthQ9KNGdoxaGUvVp","datadog":{"applicationId":"6702d87d-a7e0-42fe-bbcb-95b469547ea0","clientToken":"pub853ea8d17ad6821d9f8f11861d23dfed","rumToken":"pubf9cc52896502b9413b68ba36fc0c7162","context":{"deployment":{"target":"production","tag":"main-20241125-190609-795bd7e319","commit":"795bd7e3199e13224bc0a42c1be5cd7062eab1ad"}},"datacenter":"us"},"googleAnalyticsCode":"G-7JY7T788PK","googlePay":{"apiVersion":"2","apiVersionMinor":"0","merchantId":"BCR2DN6TV7EMTGBM","merchantName":"Medium","instanceMerchantId":"13685562959212738550"},"applePay":{"version":3},"signInWallCustomDomainCollectionIds":["3a8144eabfe3","336d898217ee","61061eb0c96b","138adf9c44c","819cc2aaeee0"],"mediumMastodonDomainName":"me.dm","mediumOwnedAndOperatedCollectionIds":["8a9336e5bb4","b7e45b22fec3","193b68bd4fba","8d6b8a439e32","54c98c43354d","3f6ecf56618","d944778ce714","92d2092dc598","ae2a65f35510","1285ba81cada","544c7006046e","fc8964313712","40187e704f1c","88d9857e584e","7b6769f2748b","bcc38c8f6edf","cef6983b292","cb8577c9149e","444d13b52878","713d7dbc99b0","ef8e90590e66","191186aaafa0","55760f21cdc5","9dc80918cc93","bdc4052bbdba","8ccfed20cbb2"],"tierOneDomains":["medium.com","thebolditalic.com","arcdigital.media","towardsdatascience.com","uxdesign.cc","codeburst.io","psiloveyou.xyz","writingcooperative.com","entrepreneurshandbook.co","prototypr.io","betterhumans.coach.me","theascent.pub"],"topicsToFollow":["d61cf867d93f","8a146bc21b28","1eca0103fff3","4d562ee63426","aef1078a3ef5","e15e46793f8d","6158eb913466","55f1c20aba7a","3d18b94f6858","4861fee224fd","63c6f1f93ee","1d98b3a9a871","decb52b64abf","ae5d4995e225","830cded25262"],"topicToTagMappings":{"accessibility":"accessibility","addiction":"addiction","android-development":"android-development","art":"art","artificial-intelligence":"artificial-intelligence","astrology":"astrology","basic-income":"basic-income","beauty":"beauty","biotech":"biotech","blockchain":"blockchain","books":"books","business":"business","cannabis":"cannabis","cities":"cities","climate-change":"climate-change","comics":"comics","coronavirus":"coronavirus","creativity":"creativity","cryptocurrency":"cryptocurrency","culture":"culture","cybersecurity":"cybersecurity","data-science":"data-science","design":"design","digital-life":"digital-life","disability":"disability","economy":"economy","education":"education","equality":"equality","family":"family","feminism":"feminism","fiction":"fiction","film":"film","fitness":"fitness","food":"food","freelancing":"freelancing","future":"future","gadgets":"gadgets","gaming":"gaming","gun-control":"gun-control","health":"health","history":"history","humor":"humor","immigration":"immigration","ios-development":"ios-development","javascript":"javascript","justice":"justice","language":"language","leadership":"leadership","lgbtqia":"lgbtqia","lifestyle":"lifestyle","machine-learning":"machine-learning","makers":"makers","marketing":"marketing","math":"math","media":"media","mental-health":"mental-health","mindfulness":"mindfulness","money":"money","music":"music","neuroscience":"neuroscience","nonfiction":"nonfiction","outdoors":"outdoors","parenting":"parenting","pets":"pets","philosophy":"philosophy","photography":"photography","podcasts":"podcast","poetry":"poetry","politics":"politics","privacy":"privacy","product-management":"product-management","productivity":"productivity","programming":"programming","psychedelics":"psychedelics","psychology":"psychology","race":"race","relationships":"relationships","religion":"religion","remote-work":"remote-work","san-francisco":"san-francisco","science":"science","self":"self","self-driving-cars":"self-driving-cars","sexuality":"sexuality","social-media":"social-media","society":"society","software-engineering":"software-engineering","space":"space","spirituality":"spirituality","sports":"sports","startups":"startup","style":"style","technology":"technology","transportation":"transportation","travel":"travel","true-crime":"true-crime","tv":"tv","ux":"ux","venture-capital":"venture-capital","visual-design":"visual-design","work":"work","world":"world","writing":"writing"},"defaultImages":{"avatar":{"imageId":"1*dmbNkD5D-u45r44go_cf0g.png","height":150,"width":150},"orgLogo":{"imageId":"7*V1_7XP4snlmqrc_0Njontw.png","height":110,"width":500},"postLogo":{"imageId":"bd978bb536350a710e8efb012513429cabdc4c28700604261aeda246d0f980b7","height":810,"width":1440},"postPreviewImage":{"imageId":"1*hn4v1tCaJy7cWMyb0bpNpQ.png","height":386,"width":579}},"collectionStructuredData":{"8d6b8a439e32":{"name":"Elemental","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F980\u002F1*9ygdqoKprhwuTVKUM0DLPA@2x.png","width":980,"height":159}}},"3f6ecf56618":{"name":"Forge","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F596\u002F1*uULpIlImcO5TDuBZ6lm7Lg@2x.png","width":596,"height":183}}},"ae2a65f35510":{"name":"GEN","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F264\u002F1*RdVZMdvfV3YiZTw6mX7yWA.png","width":264,"height":140}}},"88d9857e584e":{"name":"LEVEL","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*JqYMhNX6KNNb2UlqGqO2WQ.png","width":540,"height":108}}},"7b6769f2748b":{"name":"Marker","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fcdn-images-1.medium.com\u002Fmax\u002F383\u002F1*haCUs0wF6TgOOvfoY-jEoQ@2x.png","width":383,"height":92}}},"444d13b52878":{"name":"OneZero","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*cw32fIqCbRWzwJaoQw6BUg.png","width":540,"height":123}}},"8ccfed20cbb2":{"name":"Zora","data":{"@type":"NewsMediaOrganization","ethicsPolicy":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Farticles\u002F360043290473","logo":{"@type":"ImageObject","url":"https:\u002F\u002Fmiro.medium.com\u002Fmax\u002F540\u002F1*tZUQqRcCCZDXjjiZ4bDvgQ.png","width":540,"height":106}}}},"embeddedPostIds":{"coronavirus":"cd3010f9d81f"},"sharedCdcMessaging":{"COVID_APPLICABLE_TAG_SLUGS":[],"COVID_APPLICABLE_TOPIC_NAMES":[],"COVID_APPLICABLE_TOPIC_NAMES_FOR_TOPIC_PAGE":[],"COVID_MESSAGES":{"tierA":{"text":"For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":66,"end":73,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"tierB":{"text":"Anyone can publish on Medium per our Policies, but we don’t fact-check every story. For more info about the coronavirus, see cdc.gov.","markups":[{"start":37,"end":45,"href":"https:\u002F\u002Fhelp.medium.com\u002Fhc\u002Fen-us\u002Fcategories\u002F201931128-Policies-Safety"},{"start":125,"end":132,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"paywall":{"text":"This article has been made free for everyone, thanks to Medium Members. For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":56,"end":70,"href":"https:\u002F\u002Fmedium.com\u002Fmembership"},{"start":138,"end":145,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]},"unbound":{"text":"This article is free for everyone, thanks to Medium Members. For more information on the novel coronavirus and Covid-19, visit cdc.gov.","markups":[{"start":45,"end":59,"href":"https:\u002F\u002Fmedium.com\u002Fmembership"},{"start":127,"end":134,"href":"https:\u002F\u002Fwww.cdc.gov\u002Fcoronavirus\u002F2019-nCoV"}]}},"COVID_BANNER_POST_ID_OVERRIDE_WHITELIST":["3b31a67bff4a"]},"sharedVoteMessaging":{"TAGS":["politics","election-2020","government","us-politics","election","2020-presidential-race","trump","donald-trump","democrats","republicans","congress","republican-party","democratic-party","biden","joe-biden","maga"],"TOPICS":["politics","election"],"MESSAGE":{"text":"Find out more about the U.S. election results here.","markups":[{"start":46,"end":50,"href":"https:\u002F\u002Fcookpolitical.com\u002F2020-national-popular-vote-tracker"}]},"EXCLUDE_POSTS":["397ef29e3ca5"]},"embedPostRules":[],"recircOptions":{"v1":{"limit":3},"v2":{"limit":8}},"braintreeClientKey":"production_zjkj96jm_m56f8fqpf7ngnrd4","braintree":{"enabled":true,"merchantId":"m56f8fqpf7ngnrd4","merchantAccountId":{"usd":"AMediumCorporation_instant","eur":"amediumcorporation_EUR","cad":"amediumcorporation_CAD"},"publicKey":"ds2nn34bg2z7j5gd","braintreeEnvironment":"production","dashboardUrl":"https:\u002F\u002Fwww.braintreegateway.com\u002Fmerchants","gracePeriodDurationInDays":14,"mediumMembershipPlanId":{"monthly":"ce105f8c57a3","monthlyV2":"e8a5e126-792b-4ee6-8fba-d574c1b02fc5","monthlyWithTrial":"d5ee3dbe3db8","monthlyPremium":"fa741a9b47a2","yearly":"a40ad4a43185","yearlyV2":"3815d7d6-b8ca-4224-9b8c-182f9047866e","yearlyStaff":"d74fb811198a","yearlyWithTrial":"b3bc7350e5c7","yearlyPremium":"e21bd2c12166","monthlyOneYearFree":"e6c0637a-2bad-4171-ab4f-3c268633d83c","monthly25PercentOffFirstYear":"235ecc62-0cdb-49ae-9378-726cd21c504b","monthly20PercentOffFirstYear":"ba518864-9c13-4a99-91ca-411bf0cac756","monthly15PercentOffFirstYear":"594c029b-9f89-43d5-88f8-8173af4e070e","monthly10PercentOffFirstYear":"c6c7bc9a-40f2-4b51-8126-e28511d5bdb0","monthlyForStudents":"629ebe51-da7d-41fd-8293-34cd2f2030a8","yearlyOneYearFree":"78ba7be9-0d9f-4ece-aa3e-b54b826f2bf1","yearly25PercentOffFirstYear":"2dbb010d-bb8f-4eeb-ad5c-a08509f42d34","yearly20PercentOffFirstYear":"47565488-435b-47f8-bf93-40d5fbe0ebc8","yearly15PercentOffFirstYear":"8259809b-0881-47d9-acf7-6c001c7f720f","yearly10PercentOffFirstYear":"9dd694fb-96e1-472c-8d9e-3c868d5c1506","yearlyForStudents":"e29345ef-ab1c-4234-95c5-70e50fe6bc23","monthlyCad":"p52orjkaceei","yearlyCad":"h4q9g2up9ktt"},"braintreeDiscountId":{"oneMonthFree":"MONTHS_FREE_01","threeMonthsFree":"MONTHS_FREE_03","sixMonthsFree":"MONTHS_FREE_06","fiftyPercentOffOneYear":"FIFTY_PERCENT_OFF_ONE_YEAR"},"3DSecureVersion":"2","defaultCurrency":"usd","providerPlanIdCurrency":{"4ycw":"usd","rz3b":"usd","3kqm":"usd","jzw6":"usd","c2q2":"usd","nnsw":"usd","q8qw":"usd","d9y6":"usd","fx7w":"cad","nwf2":"cad"}},"paypalClientId":"AXj1G4fotC2GE8KzWX9mSxCH1wmPE3nJglf4Z2ig_amnhvlMVX87otaq58niAg9iuLktVNF_1WCMnN7v","paypal":{"host":"https:\u002F\u002Fapi.paypal.com:443","clientMode":"production","serverMode":"live","webhookId":"4G466076A0294510S","monthlyPlan":{"planId":"P-9WR0658853113943TMU5FDQA","name":"Medium Membership (Monthly) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"yearlyPlan":{"planId":"P-7N8963881P8875835MU5JOPQ","name":"Medium Membership (Annual) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"oneYearGift":{"name":"Medium Membership (1 Year, Digital Gift Code)","description":"Unlimited access to the best and brightest stories on Medium. Gift codes can be redeemed at medium.com\u002Fredeem.","price":"50.00","currency":"USD","sku":"membership-gift-1-yr"},"oldMonthlyPlan":{"planId":"P-96U02458LM656772MJZUVH2Y","name":"Medium Membership (Monthly)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"oldYearlyPlan":{"planId":"P-59P80963JF186412JJZU3SMI","name":"Medium Membership (Annual)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"monthlyPlanWithTrial":{"planId":"P-66C21969LR178604GJPVKUKY","name":"Medium Membership (Monthly) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"yearlyPlanWithTrial":{"planId":"P-6XW32684EX226940VKCT2MFA","name":"Medium Membership (Annual) with setup fee","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"oldMonthlyPlanNoSetupFee":{"planId":"P-4N046520HR188054PCJC7LJI","name":"Medium Membership (Monthly)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed monthly."},"oldYearlyPlanNoSetupFee":{"planId":"P-7A4913502Y5181304CJEJMXQ","name":"Medium Membership (Annual)","description":"Unlimited access to the best and brightest stories on Medium. Membership billed annually."},"sdkUrl":"https:\u002F\u002Fwww.paypal.com\u002Fsdk\u002Fjs"},"stripePublishableKey":"pk_live_7FReX44VnNIInZwrIIx6ghjl","log":{"json":true,"level":"info"},"imageUploadMaxSizeMb":25,"staffPicks":{"title":"Staff Picks","catalogId":"c7bc6e1ee00f"}},"session":{"xsrf":""}}</script><script>window.__APOLLO_STATE__ = {"ROOT_QUERY":{"__typename":"Query","viewer":null,"collectionByDomainOrSlug({\"domainOrSlug\":\"flutter-community\"})":{"__ref":"Collection:86fb29d7cc6a"},"postResult({\"id\":\"64e0c4bc4d1a\"})":{"__ref":"Post:64e0c4bc4d1a"},"userSocialLogins({\"userId\":\"70347591288a\"})":{"__typename":"UserSocialLogins","userId":"70347591288a","twitter":false,"facebook":false,"google":true,"redactedEmailAddress":"la__@g__.com","isMember":false,"emailAddress":"","userAvatar":{"__typename":"UserAvatar","username":"laurent.saerang","name":"Laurent Saerang","imageId":"0*hcKX_MBss4LUV3K4.jpg","mediumMemberAt":0}}},"ImageMetadata:":{"__typename":"ImageMetadata","id":""},"Collection:86fb29d7cc6a":{"__typename":"Collection","id":"86fb29d7cc6a","favicon":{"__ref":"ImageMetadata:"},"customStyleSheet":null,"colorPalette":{"__typename":"ColorPalette","highlightSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FFFFFFFF","colorPoints":[{"__typename":"ColorPoint","color":"#FFE2F6FF","point":0},{"__typename":"ColorPoint","color":"#FFDDF5FF","point":0.1},{"__typename":"ColorPoint","color":"#FFD7F4FF","point":0.2},{"__typename":"ColorPoint","color":"#FFD1F2FF","point":0.3},{"__typename":"ColorPoint","color":"#FFCBF1FF","point":0.4},{"__typename":"ColorPoint","color":"#FFC4F0FF","point":0.5},{"__typename":"ColorPoint","color":"#FFBEEFFF","point":0.6},{"__typename":"ColorPoint","color":"#FFB7EEFF","point":0.7},{"__typename":"ColorPoint","color":"#FFAFECFF","point":0.8},{"__typename":"ColorPoint","color":"#FFA8EBFF","point":0.9},{"__typename":"ColorPoint","color":"#FFA0EAFF","point":1}]},"defaultBackgroundSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FFFFFFFF","colorPoints":[{"__typename":"ColorPoint","color":"#FF008EE7","point":0},{"__typename":"ColorPoint","color":"#FF1184D3","point":0.1},{"__typename":"ColorPoint","color":"#FF1C7AC0","point":0.2},{"__typename":"ColorPoint","color":"#FF2270AD","point":0.3},{"__typename":"ColorPoint","color":"#FF256599","point":0.4},{"__typename":"ColorPoint","color":"#FF255A87","point":0.5},{"__typename":"ColorPoint","color":"#FF244F74","point":0.6},{"__typename":"ColorPoint","color":"#FF214361","point":0.7},{"__typename":"ColorPoint","color":"#FF1C364E","point":0.8},{"__typename":"ColorPoint","color":"#FF162A3B","point":0.9},{"__typename":"ColorPoint","color":"#FF0F1C28","point":1}]},"tintBackgroundSpectrum":{"__typename":"ColorSpectrum","backgroundColor":"#FF0091EA","colorPoints":[{"__typename":"ColorPoint","color":"#FF0091EA","point":0},{"__typename":"ColorPoint","color":"#FF3C9EEE","point":0.1},{"__typename":"ColorPoint","color":"#FF59AAF3","point":0.2},{"__typename":"ColorPoint","color":"#FF71B6F7","point":0.3},{"__typename":"ColorPoint","color":"#FF86C2FB","point":0.4},{"__typename":"ColorPoint","color":"#FF9ACDFF","point":0.5},{"__typename":"ColorPoint","color":"#FFADD8FF","point":0.6},{"__typename":"ColorPoint","color":"#FFBFE3FF","point":0.7},{"__typename":"ColorPoint","color":"#FFD1EDFF","point":0.8},{"__typename":"ColorPoint","color":"#FFE2F8FF","point":0.9},{"__typename":"ColorPoint","color":"#FFF2FFFF","point":1}]}},"domain":null,"slug":"flutter-community","googleAnalyticsId":null,"editors":[{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:91cb19edfc82"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:92720848ff49"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:8981f0c624ae"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:42f7c0123db5"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:73db6ccecfe2"}},{"__typename":"CollectionMastheadUserItem","user":{"__ref":"User:bf9bc82a0ba9"}}],"name":"Flutter Community","avatar":{"__ref":"ImageMetadata:1*nE4OFcqk2kx2-Lzhey8QKA.png"},"description":"Articles and Stories from the Flutter Community","subscriberCount":67088,"latestPostsConnection({\"paging\":{\"limit\":1}})":{"__typename":"PostConnection","posts":[{"__ref":"Post:64e0c4bc4d1a"}]},"viewerEdge":{"__ref":"CollectionViewerEdge:collectionId:86fb29d7cc6a-viewerId:lo_ca740eb3f75d"},"twitterUsername":"FlutterComm","facebookPageId":null,"logo":{"__ref":"ImageMetadata:1*4JWvD8Buzbf7cA6EfRvkiA.png"}},"User:91cb19edfc82":{"__typename":"User","id":"91cb19edfc82"},"User:92720848ff49":{"__typename":"User","id":"92720848ff49"},"User:8981f0c624ae":{"__typename":"User","id":"8981f0c624ae"},"User:42f7c0123db5":{"__typename":"User","id":"42f7c0123db5"},"User:73db6ccecfe2":{"__typename":"User","id":"73db6ccecfe2"},"User:bf9bc82a0ba9":{"__typename":"User","id":"bf9bc82a0ba9"},"ImageMetadata:1*nE4OFcqk2kx2-Lzhey8QKA.png":{"__typename":"ImageMetadata","id":"1*nE4OFcqk2kx2-Lzhey8QKA.png"},"User:2d341a775164":{"__typename":"User","id":"2d341a775164","customDomainState":null,"hasSubdomain":false,"username":"surajbhandari5502","name":"Surajbhandari","newsletterV3":{"__ref":"NewsletterV3:ddaeb40d3e7b"},"linkedAccounts":{"__ref":"LinkedAccounts:2d341a775164"},"isSuspended":false,"imageId":"1*_11O6c-R6RQbcIiJN-OSAA.png","mediumMemberAt":1729610977533,"verifications":{"__typename":"VerifiedInfo","isBookAuthor":false},"socialStats":{"__typename":"SocialStats","followerCount":113,"followingCount":1413,"collectionFollowingCount":11},"bio":"🖥️ Flutter Developer 🛠️ | 💵 Financial Explorer 📈","isPartnerProgramEnrolled":true,"viewerEdge":{"__ref":"UserViewerEdge:userId:2d341a775164-viewerId:lo_ca740eb3f75d"},"viewerIsUser":false,"postSubscribeMembershipUpsellShownAt":0,"membership":{"__ref":"Membership:bc0f55b2-25fb-4b7b-aa19-97d80032efd9"},"allowNotes":true,"twitterScreenName":""},"Post:64e0c4bc4d1a":{"__typename":"Post","id":"64e0c4bc4d1a","firstPublishedAt":1731425568345,"creator":{"__ref":"User:2d341a775164"},"collection":{"__ref":"Collection:86fb29d7cc6a"},"isSeries":false,"mediumUrl":"https:\u002F\u002Fmedium.com\u002Fflutter-community\u002Fmy-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a","sequence":null,"uniqueSlug":"my-first-step-into-unit-testing-in-flutter-simple-explanations-64e0c4bc4d1a","content({\"postMeteringOptions\":{}})":{"__typename":"PostContent","isLockedPreviewOnly":false,"bodyModel":{"__typename":"RichText","sections":[{"__typename":"Section","name":"780f","startIndex":0,"textLayout":null,"imageLayout":null,"backgroundImage":null,"videoLayout":null,"backgroundVideo":null}],"paragraphs":[{"__ref":"Paragraph:d20d8c312169_0"},{"__ref":"Paragraph:d20d8c312169_1"},{"__ref":"Paragraph:d20d8c312169_2"},{"__ref":"Paragraph:d20d8c312169_3"},{"__ref":"Paragraph:d20d8c312169_4"},{"__ref":"Paragraph:d20d8c312169_5"},{"__ref":"Paragraph:d20d8c312169_6"},{"__ref":"Paragraph:d20d8c312169_7"},{"__ref":"Paragraph:d20d8c312169_8"},{"__ref":"Paragraph:d20d8c312169_9"},{"__ref":"Paragraph:d20d8c312169_10"},{"__ref":"Paragraph:d20d8c312169_11"},{"__ref":"Paragraph:d20d8c312169_12"},{"__ref":"Paragraph:d20d8c312169_13"},{"__ref":"Paragraph:d20d8c312169_14"},{"__ref":"Paragraph:d20d8c312169_15"},{"__ref":"Paragraph:d20d8c312169_16"},{"__ref":"Paragraph:d20d8c312169_17"},{"__ref":"Paragraph:d20d8c312169_18"},{"__ref":"Paragraph:d20d8c312169_19"},{"__ref":"Paragraph:d20d8c312169_20"},{"__ref":"Paragraph:d20d8c312169_21"},{"__ref":"Paragraph:d20d8c312169_22"},{"__ref":"Paragraph:d20d8c312169_23"},{"__ref":"Paragraph:d20d8c312169_24"},{"__ref":"Paragraph:d20d8c312169_25"},{"__ref":"Paragraph:d20d8c312169_26"},{"__ref":"Paragraph:d20d8c312169_27"},{"__ref":"Paragraph:d20d8c312169_28"},{"__ref":"Paragraph:d20d8c312169_29"},{"__ref":"Paragraph:d20d8c312169_30"},{"__ref":"Paragraph:d20d8c312169_31"},{"__ref":"Paragraph:d20d8c312169_32"},{"__ref":"Paragraph:d20d8c312169_33"},{"__ref":"Paragraph:d20d8c312169_34"},{"__ref":"Paragraph:d20d8c312169_35"},{"__ref":"Paragraph:d20d8c312169_36"},{"__ref":"Paragraph:d20d8c312169_37"},{"__ref":"Paragraph:d20d8c312169_38"},{"__ref":"Paragraph:d20d8c312169_39"},{"__ref":"Paragraph:d20d8c312169_40"},{"__ref":"Paragraph:d20d8c312169_41"},{"__ref":"Paragraph:d20d8c312169_42"},{"__ref":"Paragraph:d20d8c312169_43"},{"__ref":"Paragraph:d20d8c312169_44"},{"__ref":"Paragraph:d20d8c312169_45"},{"__ref":"Paragraph:d20d8c312169_46"},{"__ref":"Paragraph:d20d8c312169_47"},{"__ref":"Paragraph:d20d8c312169_48"},{"__ref":"Paragraph:d20d8c312169_49"},{"__ref":"Paragraph:d20d8c312169_50"},{"__ref":"Paragraph:d20d8c312169_51"},{"__ref":"Paragraph:d20d8c312169_52"},{"__ref":"Paragraph:d20d8c312169_53"},{"__ref":"Paragraph:d20d8c312169_54"},{"__ref":"Paragraph:d20d8c312169_55"},{"__ref":"Paragraph:d20d8c312169_56"},{"__ref":"Paragraph:d20d8c312169_57"},{"__ref":"Paragraph:d20d8c312169_58"},{"__ref":"Paragraph:d20d8c312169_59"},{"__ref":"Paragraph:d20d8c312169_60"},{"__ref":"Paragraph:d20d8c312169_61"},{"__ref":"Paragraph:d20d8c312169_62"},{"__ref":"Paragraph:d20d8c312169_63"},{"__ref":"Paragraph:d20d8c312169_64"},{"__ref":"Paragraph:d20d8c312169_65"},{"__ref":"Paragraph:d20d8c312169_66"}]},"validatedShareKey":"","shareKeyCreator":null},"inResponseToEntityType":null,"isLocked":false,"isMarkedPaywallOnly":false,"lockedSource":"LOCKED_POST_SOURCE_NONE","primaryTopic":null,"topics":[{"__typename":"Topic","slug":"programming"}],"isPublished":true,"latestPublishedVersion":"d20d8c312169","visibility":"PUBLIC","postResponses":{"__typename":"PostResponses","count":0},"clapCount":37,"allowResponses":true,"isLimitedState":false,"title":"My First Step into Unit Testing in Flutter: Simple Explanations","socialTitle":"","socialDek":"","canonicalUrl":"","metaDescription":"","latestPublishedAt":1732472619331,"readingTime":7.221698113207547,"previewContent":{"__typename":"PreviewContent","subtitle":"Testing used to be a boring side for me."},"previewImage":{"__ref":"ImageMetadata:1*iHGUNxLXc7mKwpqKw5JAOw.png"},"isShortform":false,"seoTitle":"","updatedAt":1732472619331,"shortformType":"SHORTFORM_TYPE_LINK","seoDescription":"","viewerEdge":{"__ref":"PostViewerEdge:postId:64e0c4bc4d1a-viewerId:lo_ca740eb3f75d"},"isSuspended":false,"license":"ALL_RIGHTS_RESERVED","tags":[{"__ref":"Tag:programming"},{"__ref":"Tag:technology"},{"__ref":"Tag:software-development"},{"__ref":"Tag:flutter"},{"__ref":"Tag:flutter-app-development"}],"isNewsletter":false,"statusForCollection":"APPROVED","pendingCollection":null,"detectedLanguage":"en","wordCount":1662,"layerCake":0,"responsesLocked":false},"LinkedAccounts:2d341a775164":{"__typename":"LinkedAccounts","mastodon":null,"id":"2d341a775164"},"UserViewerEdge:userId:2d341a775164-viewerId:lo_ca740eb3f75d":{"__typename":"UserViewerEdge","id":"userId:2d341a775164-viewerId:lo_ca740eb3f75d","isFollowing":false,"isUser":false,"isMuting":false},"NewsletterV3:ddaeb40d3e7b":{"__typename":"NewsletterV3","id":"ddaeb40d3e7b","type":"NEWSLETTER_TYPE_AUTHOR","slug":"2d341a775164","name":"2d341a775164","collection":null,"user":{"__ref":"User:2d341a775164"}},"Membership:bc0f55b2-25fb-4b7b-aa19-97d80032efd9":{"__typename":"Membership","tier":"MEMBER","id":"bc0f55b2-25fb-4b7b-aa19-97d80032efd9"},"Paragraph:d20d8c312169_0":{"__typename":"Paragraph","id":"d20d8c312169_0","name":"0e43","type":"H3","href":null,"layout":null,"metadata":null,"text":"My First Step into Unit Testing in Flutter: Simple Explanations","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_1":{"__typename":"Paragraph","id":"d20d8c312169_1","name":"3c65","type":"H4","href":null,"layout":null,"metadata":null,"text":"Testing used to be a boring side for me.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*iHGUNxLXc7mKwpqKw5JAOw.png":{"__typename":"ImageMetadata","id":"1*iHGUNxLXc7mKwpqKw5JAOw.png","originalHeight":1080,"originalWidth":1080,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:d20d8c312169_2":{"__typename":"Paragraph","id":"d20d8c312169_2","name":"52a5","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*iHGUNxLXc7mKwpqKw5JAOw.png"},"text":"Image by author","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_3":{"__typename":"Paragraph","id":"d20d8c312169_3","name":"fcd5","type":"P","href":null,"layout":null,"metadata":null,"text":"I have been involved with Flutter for the past three years. I was busy running a race for a good Flutter developer.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_4":{"__typename":"Paragraph","id":"d20d8c312169_4","name":"7b62","type":"P","href":null,"layout":null,"metadata":null,"text":"One day I heard about Test Driven Development (TDD), which is an approach to writing test cases before actual code is written for an app.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_5":{"__typename":"Paragraph","id":"d20d8c312169_5","name":"3092","type":"P","href":null,"layout":null,"metadata":null,"text":"When I started writing BOOM!! I did not meet my deadline for the feature I needed to implement in my project. Since testing was not mandatory on that project, I left and got busy directly writing the actual code, forgetting about test cases.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_6":{"__typename":"Paragraph","id":"d20d8c312169_6","name":"ab15","type":"BQ","href":null,"layout":null,"metadata":null,"text":"Again, after 2 years, I am here, thinking of writing test cases with different energy. FINALLY!!","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:0*tuIIdg1RChof-AwD.gif":{"__typename":"ImageMetadata","id":"0*tuIIdg1RChof-AwD.gif","originalHeight":498,"originalWidth":498,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:d20d8c312169_7":{"__typename":"Paragraph","id":"d20d8c312169_7","name":"689f","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:0*tuIIdg1RChof-AwD.gif"},"text":"Gif Source: tenor","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":12,"end":17,"href":"https:\u002F\u002Ftenor.com\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_8":{"__typename":"Paragraph","id":"d20d8c312169_8","name":"50f0","type":"P","href":null,"layout":null,"metadata":null,"text":"Let me tell you what I found when I explored how testing in Flutter works in real apps.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":45,"end":87,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_9":{"__typename":"Paragraph","id":"d20d8c312169_9","name":"2f05","type":"P","href":null,"layout":null,"metadata":null,"text":"I wanna also inform you that it’s not necessary to connect any device or emulator to run test cases. In this story, I will go with the basic structure of a test case which will test your actual code.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_10":{"__typename":"Paragraph","id":"d20d8c312169_10","name":"a312","type":"P","href":null,"layout":null,"metadata":null,"text":"The test case code is written under the test Folder (This folder is like the 2nd page of a Google search, very few developers go there 😅).","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"EM","start":40,"end":45,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_11":{"__typename":"Paragraph","id":"d20d8c312169_11","name":"62ff","type":"P","href":null,"layout":null,"metadata":null,"text":"I would like to inform you that we will talk about new main() method that will act as the root of the testing process.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":55,"end":61,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_12":{"__typename":"Paragraph","id":"d20d8c312169_12","name":"4927","type":"P","href":null,"layout":null,"metadata":null,"text":"The below picture is the basic structure of test cases.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*u4H-RKl35a4NU6E2MduZMw.png":{"__typename":"ImageMetadata","id":"1*u4H-RKl35a4NU6E2MduZMw.png","originalHeight":442,"originalWidth":570,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:d20d8c312169_13":{"__typename":"Paragraph","id":"d20d8c312169_13","name":"6ab5","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*u4H-RKl35a4NU6E2MduZMw.png"},"text":"Basic structure for writing test code (Image by Author)","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_14":{"__typename":"Paragraph","id":"d20d8c312169_14","name":"10dc","type":"P","href":null,"layout":null,"metadata":null,"text":"Arrange, Act, and Assert, are the 3 blocks of a test method that a developer has to follow.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":0,"end":7,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":9,"end":14,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":18,"end":24,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_15":{"__typename":"Paragraph","id":"d20d8c312169_15","name":"eb13","type":"P","href":null,"layout":null,"metadata":null,"text":"Remember in the TDD approach we will write test cases first followed by writing actual code. we say it as the Red-Green-Refactor cycle.","hasDropCap":true,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":110,"end":129,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":134,"end":135,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_16":{"__typename":"Paragraph","id":"d20d8c312169_16","name":"ef21","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Red: 🛑 It is called red because here your test case will surely fail. It fails because since the test case is written before the actual code so in this step your test case will not find the actual code that is going to be tested.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":0,"end":3,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_17":{"__typename":"Paragraph","id":"d20d8c312169_17","name":"93a3","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Green: 💚Here your test case gets passed. This step takes place only after you have written your actual code that needs to be tested. Remember here you will make the test pass with minimum test code.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":0,"end":7,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"EM","start":181,"end":198,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_18":{"__typename":"Paragraph","id":"d20d8c312169_18","name":"b2c6","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Refactor:🔧 You will improve your test code although test cases are still passing.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":0,"end":9,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":11,"end":12,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_19":{"__typename":"Paragraph","id":"d20d8c312169_19","name":"ffbb","type":"P","href":null,"layout":null,"metadata":null,"text":"Let me show you an example to write a unit test for a very simple function.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_20":{"__typename":"Paragraph","id":"d20d8c312169_20","name":"c64c","type":"P","href":null,"layout":null,"metadata":null,"text":"Suppose I have a Counter class somewhere in the lib folder with two methods increment() and decrement() .","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":17,"end":24,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":76,"end":87,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":92,"end":103,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_21":{"__typename":"Paragraph","id":"d20d8c312169_21","name":"b53e","type":"PRE","href":null,"layout":null,"metadata":null,"text":"class Counter {\n\n int value=0;\n\n\nvoid increment(){\n\n value ++\n\n}\n\nvoid decrement(){\n\n value --\n\n}\n\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"EXPLICIT","lang":"dart"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_22":{"__typename":"Paragraph","id":"d20d8c312169_22","name":"d121","type":"P","href":null,"layout":null,"metadata":null,"text":"Let's write a test code for them. I mean to say let's go to Google search page no .2 😅 , Just for fun.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_23":{"__typename":"Paragraph","id":"d20d8c312169_23","name":"8e48","type":"P","href":null,"layout":null,"metadata":null,"text":"Here we will open a folder called “test” which is just inside your root folder of a project, If you don't have create it.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_24":{"__typename":"Paragraph","id":"d20d8c312169_24","name":"7da1","type":"P","href":null,"layout":null,"metadata":null,"text":"Inside this folder, I will write a test code for the above methods.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_25":{"__typename":"Paragraph","id":"d20d8c312169_25","name":"df15","type":"PRE","href":null,"layout":null,"metadata":null,"text":"void main() {\n group('Counter', () {\n\n test('initial value should be 0', () {\n\n \u002F\u002F Arrange\n final counter = Counter();\n\n \u002F\u002F Act\n \u002F\u002F[ No action needed as we're just checking the initial value].\n\n \u002F\u002F Assert\n expect(counter.value, 0);\n });\n\n\n\n test('increment should increase value by 1', () {\n\n \u002F\u002F Arrange\n final counter = Counter();\n\n \u002F\u002F Act\n counter.increment();\n\n \u002F\u002F Assert\n expect(counter.value, 1);\n });\n\n\n test('decrement should decrease value by 1', () {\n\n \u002F\u002F Arrange\n final counter = Counter();\n\n \u002F\u002F Act\n counter.decrement();\n\n \u002F\u002F Assert\n expect(counter.value, -1);\n });\n });\n}\n\n\u002F\u002F\u002FNotes:\n\n\u002F\u002F\u002Fgroup() : It is the collection of similar test cases which helps to organize tests well.\n\u002F\u002F\u002Ftest() : Defines a single test with description and cases.\n","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"EXPLICIT","lang":"dart"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_26":{"__typename":"Paragraph","id":"d20d8c312169_26","name":"6212","type":"P","href":null,"layout":null,"metadata":null,"text":"Remember to follow the Red-Green-Refactor cycle.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":23,"end":42,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_27":{"__typename":"Paragraph","id":"d20d8c312169_27","name":"22ca","type":"P","href":null,"layout":null,"metadata":null,"text":"If I run the test, It will pass all of them as shown in the image below.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*cWG4DCata-tk3_PggKZABQ.png":{"__typename":"ImageMetadata","id":"1*cWG4DCata-tk3_PggKZABQ.png","originalHeight":266,"originalWidth":1289,"focusPercentX":null,"focusPercentY":null,"alt":"Image showing passing test cases in flutter."},"Paragraph:d20d8c312169_28":{"__typename":"Paragraph","id":"d20d8c312169_28","name":"edc6","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*cWG4DCata-tk3_PggKZABQ.png"},"text":"Image showing passing test cases.(Image by Author)","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_29":{"__typename":"Paragraph","id":"d20d8c312169_29","name":"201c","type":"BQ","href":null,"layout":null,"metadata":null,"text":"Yahoo!! I guess we have completed the first level of testing actual code in flutter.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_30":{"__typename":"Paragraph","id":"d20d8c312169_30","name":"810b","type":"P","href":null,"layout":null,"metadata":null,"text":"This is what you need to know for writing basic unit tests in Flutter.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_31":{"__typename":"Paragraph","id":"d20d8c312169_31","name":"5912","type":"P","href":null,"layout":null,"metadata":null,"text":"Now let's push our leg to another level. Wait !! It's easy, just stay with me.","hasDropCap":true,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_32":{"__typename":"Paragraph","id":"d20d8c312169_32","name":"97b3","type":"BQ","href":null,"layout":null,"metadata":null,"text":"Remember you will not call any external library or any API calls in unit testing.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_33":{"__typename":"Paragraph","id":"d20d8c312169_33","name":"e788","type":"P","href":null,"layout":null,"metadata":null,"text":"So, how will I know if my repository is working properly during API calls or if the external library is used properly?","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:0*__nnM87gy1opu7N-.gif":{"__typename":"ImageMetadata","id":"0*__nnM87gy1opu7N-.gif","originalHeight":476,"originalWidth":640,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:d20d8c312169_34":{"__typename":"Paragraph","id":"d20d8c312169_34","name":"7b89","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:0*__nnM87gy1opu7N-.gif"},"text":"Gif Source: tenor","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":12,"end":17,"href":"https:\u002F\u002Ftenor.com\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_35":{"__typename":"Paragraph","id":"d20d8c312169_35","name":"06c7","type":"BQ","href":null,"layout":null,"metadata":null,"text":"Here comes Mocking !","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":11,"end":20,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_36":{"__typename":"Paragraph","id":"d20d8c312169_36","name":"0c90","type":"P","href":null,"layout":null,"metadata":null,"text":"Yeah, we can mock these with their fake objects.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_37":{"__typename":"Paragraph","id":"d20d8c312169_37","name":"b78c","type":"P","href":null,"layout":null,"metadata":null,"text":"mockito package is commonly used for creating mocks in Flutter. You can get it from here. You will also need build_runner package to generate mocks automatically.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":0,"end":7,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":109,"end":121,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":84,"end":88,"href":"https:\u002F\u002Fpub.dev\u002Fpackages\u002Fmockito","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_38":{"__typename":"Paragraph","id":"d20d8c312169_38","name":"5972","type":"P","href":null,"layout":null,"metadata":null,"text":"I wanna show you how I did a mocking of an API call in my project. I am willing to show you the API call to log in to the app.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_39":{"__typename":"Paragraph","id":"d20d8c312169_39","name":"6c6c","type":"P","href":null,"layout":null,"metadata":null,"text":"Please see some code that I have written for my project.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_40":{"__typename":"Paragraph","id":"d20d8c312169_40","name":"0821","type":"P","href":null,"layout":null,"metadata":null,"text":"Note: I am using flutter_riverpod as a state management technique in my app.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":17,"end":34,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"A","start":17,"end":34,"href":"https:\u002F\u002Fpub.dev\u002Fpackages\u002Fflutter_riverpod","anchorType":"LINK","userId":null,"linkMetadata":null},{"__typename":"Markup","type":"EM","start":0,"end":76,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_41":{"__typename":"Paragraph","id":"d20d8c312169_41","name":"8ee0","type":"P","href":null,"layout":null,"metadata":null,"text":"This is inside the Controller Folder, where I have the following method which will call API from the Repository folder (I will show you Repo later):","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_42":{"__typename":"Paragraph","id":"d20d8c312169_42","name":"15db","type":"PRE","href":null,"layout":null,"metadata":null,"text":"class AuthController extends StateNotifier\u003CBaseState\u003Cdynamic\u003E\u003E {\n AuthController(this._read) : super(const BaseState\u003Cvoid\u003E.initial());\n\n final StateNotifierProviderRef\u003Cdynamic, dynamic\u003E _read;\n\n IAuthRepository get _repo =\u003E _read.read(authRepository);\n\n\n\nFuture\u003Cvoid\u003E loginUser({\n required LoginRequest loginRequest,\n }) async {\n state = const BaseState.loading();\n final response = await _repo.login(loginRequest: loginRequest);\n state = response.fold(\n (loginSuccess) {\n return BaseState.success(data: loginSuccess);\n },\n (error) {\n return BaseState.error(error);\n },\n );\n }\n\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"EXPLICIT","lang":"dart"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_43":{"__typename":"Paragraph","id":"d20d8c312169_43","name":"8be6","type":"P","href":null,"layout":null,"metadata":null,"text":"Basically above code shows that loginUser methods is calling another method from repository to call an API.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":32,"end":41,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_44":{"__typename":"Paragraph","id":"d20d8c312169_44","name":"c1c1","type":"P","href":null,"layout":null,"metadata":null,"text":"Let me show you how you can write unit tests for the above loginUser method.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":59,"end":68,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_45":{"__typename":"Paragraph","id":"d20d8c312169_45","name":"8e08","type":"P","href":null,"layout":null,"metadata":null,"text":"Let me show you how my Ripo looks :","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_46":{"__typename":"Paragraph","id":"d20d8c312169_46","name":"80d6","type":"PRE","href":null,"layout":null,"metadata":null,"text":"abstract class IAuthRepository {\n Future\u003CEither\u003CLoginResponse, Failure\u003E\u003E login({\n required LoginRequest loginRequest,\n });\n\n\n @override\n Future\u003CEither\u003CLoginResponse, Failure\u003E\u003E login({\n required LoginRequest loginRequest,\n }) async {\n try {\n final response = await _apiHelper.post(\n endPoint: ApiEndpoints.loginEndpoint,\n data: loginRequest.toJson(),\n );\n\n final data =\n LoginResponse.fromJson(response.data as Map\u003CString, dynamic\u003E);\n if (data.isSuccess) {\n return Left(data);\n } else {\n return Right(Failure.fromException(\"Something went wrong\"));\n }\n } catch (e) {\n return Right(Failure.fromException(e));\n }\n }\n","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"EXPLICIT","lang":"dart"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_47":{"__typename":"Paragraph","id":"d20d8c312169_47","name":"196f","type":"P","href":null,"layout":null,"metadata":null,"text":"The above method is called a post method to call login API. Here if Login fails it returns Failure in the Right of Either else LoginResponse is returned in Left of Either.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":29,"end":33,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":91,"end":98,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":115,"end":121,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":127,"end":140,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":156,"end":160,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":164,"end":171,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_48":{"__typename":"Paragraph","id":"d20d8c312169_48","name":"d342","type":"P","href":null,"layout":null,"metadata":null,"text":"Now finally dive into the test folder. I will explain the code below. Here, I am trying to comment on each line of code so that none of the developers will get into trouble while reading.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_49":{"__typename":"Paragraph","id":"d20d8c312169_49","name":"da4f","type":"PRE","href":null,"layout":null,"metadata":null,"text":"\u002F\u002F Import the necessary packages and classes\n\u002F\u002F Generate a Mock class for IAuthRepository\n@GenerateMocks([IAuthRepository])\nvoid main() {\n \u002F\u002F Declare variables for test setup\n late ProviderContainer container; \u002F\u002F Used to manage dependencies and overrides during tests\n late MockIAuthRepository mockAuthRepository; \u002F\u002F Mock object for IAuthRepository to simulate login behavior\n late LoginRequest loginRequest; \u002F\u002F Object to represent the login request data\n late LoginResponse loginSuccessResponse; \u002F\u002F Object to represent a successful login response\n late Failure loginFailureResponse; \u002F\u002F Object to represent a failed login response\n\n \u002F\u002F setUp() function runs before each test, initializing necessary objects\n setUp(() {\n \u002F\u002F Initialize the mock repository and login request details\n mockAuthRepository = MockIAuthRepository();\n loginRequest = LoginRequest(\n username: 'testUser',\n password: 'password123',\n );\n\n \u002F\u002F Define a successful login response for the mock repository to return\n loginSuccessResponse = LoginResponse(\n accessToken: \"accessToken\",\n isSuccess: true,\n configuration: [],\n userName: \"userName\");\n\n \u002F\u002F Define a failure response\n loginFailureResponse = Failure('got issue', FailureType.exception);\n\n \u002F\u002F Create a ProviderContainer to manage providers during tests\n container = ProviderContainer(\n overrides: [\n \u002F\u002F Override the authRepository provider with our mock repository\n authRepository.overrideWithValue(mockAuthRepository),\n ],\n );\n });\n\n \u002F\u002F tearDown() function runs after each test, cleaning up resources\n tearDown(() {\n container.dispose(); \u002F\u002F Dispose of the container to free up resources\n });\n\n \u002F\u002F Group related tests for the loginUser function\n group('loginUser', () {\n \u002F\u002F Test the success scenario of loginUser\n test('emits loading and success states when login is successful', () async {\n \u002F\u002F Arrange: Set up the mockAuthRepository to return a successful login response\n when(mockAuthRepository.login(loginRequest: loginRequest))\n .thenAnswer((_) async =\u003E Left(loginSuccessResponse));\n\n \u002F\u002F Act: Retrieve the authController from the provider container\n final authController = container.read(loginController.notifier);\n\n \u002F\u002F Assert: Verify initial state is `initial`\n expect(authController.state, const BaseState\u003Cvoid\u003E.initial());\n\n \u002F\u002F Act: Trigger the loginUser function and verify loading state\n final future = authController.loginUser(loginRequest: loginRequest);\n expect(authController.state, const BaseState.loading());\n\n \u002F\u002F Wait for the future to complete\n await future;\n print('result: ${authController.state}');\n\n \u002F\u002F Assert: Verify the final state is success with the expected login response data\n expect(authController.state,\n BaseState\u003Cdynamic\u003E.success(data: loginSuccessResponse));\n });\n });\n}","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":{"__typename":"CodeBlockMetadata","mode":"AUTO","lang":"dart"},"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_50":{"__typename":"Paragraph","id":"d20d8c312169_50","name":"c363","type":"P","href":null,"layout":null,"metadata":null,"text":"This is how my output is seen in the terminal after running the test.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"ImageMetadata:1*lulA1ey1JY1cBIpR4bSS9g.png":{"__typename":"ImageMetadata","id":"1*lulA1ey1JY1cBIpR4bSS9g.png","originalHeight":350,"originalWidth":734,"focusPercentX":null,"focusPercentY":null,"alt":null},"Paragraph:d20d8c312169_51":{"__typename":"Paragraph","id":"d20d8c312169_51","name":"d0cc","type":"IMG","href":null,"layout":"INSET_CENTER","metadata":{"__ref":"ImageMetadata:1*lulA1ey1JY1cBIpR4bSS9g.png"},"text":"Image to show a test is passed successfully(Image by Author)","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_52":{"__typename":"Paragraph","id":"d20d8c312169_52","name":"4437","type":"H4","href":null,"layout":null,"metadata":null,"text":"Code Explanation","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_53":{"__typename":"Paragraph","id":"d20d8c312169_53","name":"df2b","type":"OLI","href":null,"layout":null,"metadata":null,"text":"Setup and Mocking:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":0,"end":18,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_54":{"__typename":"Paragraph","id":"d20d8c312169_54","name":"d5e7","type":"ULI","href":null,"layout":null,"metadata":null,"text":"mockito’s @GenerateMocksannotation is an instruction to generate a mock class for the IAuthRepository . This is a management tool that allows a mock class to successfully copy the behavior of the original class.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":0,"end":7,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":10,"end":24,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":86,"end":102,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_55":{"__typename":"Paragraph","id":"d20d8c312169_55","name":"8b87","type":"ULI","href":null,"layout":null,"metadata":null,"text":"In the setUp function, the login request, the successful login response, and the failure response are initialized. \nWe instantiate a ProviderContainerthat handles the dependencies. In this case, we use a mock version to override authRepository. In this case, it makes it possible to control the operations that authenticate are subjected to the tests.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":7,"end":13,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":133,"end":150,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":229,"end":243,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_56":{"__typename":"Paragraph","id":"d20d8c312169_56","name":"5809","type":"P","href":null,"layout":null,"metadata":null,"text":"2. Test Case for loginUser:","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":17,"end":26,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":3,"end":26,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_57":{"__typename":"Paragraph","id":"d20d8c312169_57","name":"10ab","type":"ULI","href":null,"layout":null,"metadata":null,"text":"The test that \"emits loading and success states when login is successful\"is to check whether the loginUsermethod when the operation is over with the successful login.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":14,"end":73,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":97,"end":106,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_58":{"__typename":"Paragraph","id":"d20d8c312169_58","name":"e378","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Arrange: It covers the situation when mockAuthRepository.login() should return a login response (with success).","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":38,"end":64,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":0,"end":7,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_59":{"__typename":"Paragraph","id":"d20d8c312169_59","name":"80b7","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Act: It brings in the authControllerand calls loginUser(), . Before awaiting the result, the authControllerstate is inspected to make sure that it goes from the initialto loadingstages.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"CODE","start":22,"end":36,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":46,"end":58,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":93,"end":107,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":161,"end":168,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"CODE","start":171,"end":178,"href":null,"anchorType":null,"userId":null,"linkMetadata":null},{"__typename":"Markup","type":"STRONG","start":0,"end":3,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_60":{"__typename":"Paragraph","id":"d20d8c312169_60","name":"5e1a","type":"ULI","href":null,"layout":null,"metadata":null,"text":"Assert: After the login is completed, check that the state has been changed to a successful state with the appropriate data.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"STRONG","start":0,"end":7,"href":null,"anchorType":null,"userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_61":{"__typename":"Paragraph","id":"d20d8c312169_61","name":"28cc","type":"H3","href":null,"layout":null,"metadata":null,"text":"Final words","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_62":{"__typename":"Paragraph","id":"d20d8c312169_62","name":"384f","type":"P","href":null,"layout":null,"metadata":null,"text":"This is what I have learned till now, So If you have any questions or feedback please do comment.","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_63":{"__typename":"Paragraph","id":"d20d8c312169_63","name":"f724","type":"P","href":null,"layout":null,"metadata":null,"text":"I request you to check this article regularly because I am planning to add more things here in the future to make it better for you and a lot easier to understand what is happening. For now, please do Clap! and I am signing off for today. Ta! Ta! 👋🏻👋🏻👋🏻","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_64":{"__typename":"Paragraph","id":"d20d8c312169_64","name":"927b","type":"H4","href":null,"layout":null,"metadata":null,"text":"(☞ ͡° ͜ʖ ͡°)☞ Please follow me for further updates on Flutter!","hasDropCap":null,"dropCapImage":null,"markups":[],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_65":{"__typename":"Paragraph","id":"d20d8c312169_65","name":"fba6","type":"P","href":null,"layout":null,"metadata":null,"text":"Buy me a coffee ☕️","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":0,"end":15,"href":"http:\u002F\u002Fbuymeacoffee.com\u002Fsurajbhand","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"Paragraph:d20d8c312169_66":{"__typename":"Paragraph","id":"d20d8c312169_66","name":"7c34","type":"P","href":null,"layout":null,"metadata":null,"text":"For more on Flutter Framework please check out here.","hasDropCap":null,"dropCapImage":null,"markups":[{"__typename":"Markup","type":"A","start":0,"end":52,"href":"https:\u002F\u002Fsurajbhandari.info\u002F","anchorType":"LINK","userId":null,"linkMetadata":null}],"codeBlockMetadata":null,"iframe":null,"mixtapeMetadata":null},"CollectionViewerEdge:collectionId:86fb29d7cc6a-viewerId:lo_ca740eb3f75d":{"__typename":"CollectionViewerEdge","id":"collectionId:86fb29d7cc6a-viewerId:lo_ca740eb3f75d","isEditor":false,"isMuting":false},"ImageMetadata:1*4JWvD8Buzbf7cA6EfRvkiA.png":{"__typename":"ImageMetadata","id":"1*4JWvD8Buzbf7cA6EfRvkiA.png","originalWidth":375,"originalHeight":54},"PostViewerEdge:postId:64e0c4bc4d1a-viewerId:lo_ca740eb3f75d":{"__typename":"PostViewerEdge","shouldIndexPostForExternalSearch":true,"id":"postId:64e0c4bc4d1a-viewerId:lo_ca740eb3f75d"},"Tag:programming":{"__typename":"Tag","id":"programming","displayTitle":"Programming","normalizedTagSlug":"programming"},"Tag:technology":{"__typename":"Tag","id":"technology","displayTitle":"Technology","normalizedTagSlug":"technology"},"Tag:software-development":{"__typename":"Tag","id":"software-development","displayTitle":"Software Development","normalizedTagSlug":"software-development"},"Tag:flutter":{"__typename":"Tag","id":"flutter","displayTitle":"Flutter","normalizedTagSlug":"flutter"},"Tag:flutter-app-development":{"__typename":"Tag","id":"flutter-app-development","displayTitle":"Flutter App Development","normalizedTagSlug":"flutter-app-development"}}</script><script>window.__MIDDLEWARE_STATE__={"session":{"xsrf":""},"cache":{"cacheStatus":"HIT"}}</script><script src="https://cdn-client.medium.com/lite/static/js/manifest.de931270.js"></script><script src="https://cdn-client.medium.com/lite/static/js/9865.1496d74a.js"></script><script src="https://cdn-client.medium.com/lite/static/js/main.3947a59c.js"></script><script src="https://cdn-client.medium.com/lite/static/js/instrumentation.d9108df7.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/reporting.ff22a7a5.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/9120.5df29668.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5049.d1ead72d.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/4810.6318add7.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6618.db187378.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2707.b0942613.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/9977.5b3eb23a.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8599.1ab63137.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5250.9f9e01d2.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6349.b071a958.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2648.26563adf.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8393.826a25fb.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7079.67349d50.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/3735.afb7e926.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/5642.a2d9f6a1.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6546.cd03f950.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/6834.08de95de.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7346.72622eb9.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2420.2a5e2d95.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/839.ca7937c2.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7975.d195c6f1.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2106.21ff89d3.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/7394.3d049572.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/2961.00a48598.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/8204.c4082863.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/4391.59acaed3.chunk.js"></script> <script src="https://cdn-client.medium.com/lite/static/js/PostPage.MainContent.c8a11795.chunk.js"></script><script>window.main();</script><script>(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'8e8ecc2c999c9cf9',t:'MTczMjY3NTY4OC4wMDAwMDA='};var a=document.createElement('script');a.nonce='';a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10