blob: 413a97a1b752be913d474c84f45d84f75ba9e866 [file] [log] [blame]
<!doctype html>
<html class="docs-version-current" lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="generator" content="Docusaurus v2.0.0-beta.14">
<link rel="alternate" type="application/rss+xml" href="/blog/rss.xml" title="Apache Linkis Blog RSS Feed">
<link rel="alternate" type="application/atom+xml" href="/blog/atom.xml" title="Apache Linkis Blog Atom Feed">
<link rel="search" type="application/opensearchdescription+xml" title="Apache Linkis" href="/opensearch.xml"><title data-react-helmet="true">How to Write Unit Test Code | Apache Linkis</title><meta data-react-helmet="true" name="twitter:card" content="summary_large_image"><meta data-react-helmet="true" property="og:url" content="https://linkis.incubator.apache.org/community/how-to-write-unit-test-code"><meta data-react-helmet="true" name="docsearch:language" content="en"><meta data-react-helmet="true" name="docsearch:version" content="current"><meta data-react-helmet="true" name="docsearch:docusaurus_tag" content="docs-community-current"><meta data-react-helmet="true" property="og:title" content="How to Write Unit Test Code | Apache Linkis"><meta data-react-helmet="true" name="description" content="Frame Selection"><meta data-react-helmet="true" property="og:description" content="Frame Selection"><link data-react-helmet="true" rel="shortcut icon" href="/img/favicon.ico"><link data-react-helmet="true" rel="canonical" href="https://linkis.incubator.apache.org/community/how-to-write-unit-test-code"><link data-react-helmet="true" rel="alternate" href="https://linkis.incubator.apache.org/community/how-to-write-unit-test-code" hreflang="en"><link data-react-helmet="true" rel="alternate" href="https://linkis.incubator.apache.org/zh-CN/community/how-to-write-unit-test-code" hreflang="zh-CN"><link data-react-helmet="true" rel="alternate" href="https://linkis.incubator.apache.org/community/how-to-write-unit-test-code" hreflang="x-default"><link data-react-helmet="true" rel="preconnect" href="https://AE29KQB3IA-dsn.algolia.net" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.92d87943.css">
<link rel="preload" href="/assets/js/runtime~main.a4c60f50.js" as="script">
<link rel="preload" href="/assets/js/main.42471b13.js" as="script">
</head>
<body>
<script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}()</script><div id="__docusaurus">
<div><a href="#" class="skipToContent_OuoZ">Skip to main content</a></div><nav class="navbar navbar--fixed-top"><div class="navbar__inner"><div class="navbar__items"><button aria-label="Navigation bar toggle" class="navbar__toggle clean-btn" type="button" tabindex="0"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/"><img src="/img/logo.png" alt="Apache Linkis Logo" class="themedImage_TMUO themedImage--light_4Vu1 navbar__logo"><img src="/img/logo.png" alt="Apache Linkis Logo" class="themedImage_TMUO themedImage--dark_uzRr navbar__logo"><b class="navbar__title">Apache Linkis(Incubating)</b></a><a class="navbar__item navbar__link" href="/">Home</a><a class="navbar__item navbar__link" href="/faq/main">FAQ</a><a class="navbar__item navbar__link" href="/download/main">Download</a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/community/how-to-subscribe">Community</a><a class="navbar__item navbar__link" href="/blog">Blog</a><a class="navbar__item navbar__link" href="/team">Team</a><a class="navbar__item navbar__link" href="/user">Users</a><div class="navbar__item dropdown dropdown--hoverable"><a class="navbar__link">ASF</a><ul class="dropdown__menu"><li><a href="https://www.apache.org/" target="_blank" rel="noopener noreferrer" class="dropdown__link">Foundation</a></li><li><a href="https://www.apache.org/licenses/" target="_blank" rel="noopener noreferrer" class="dropdown__link">License</a></li><li><a href="https://www.apache.org/events/current-event" target="_blank" rel="noopener noreferrer" class="dropdown__link">Events</a></li><li><a href="https://www.apache.org/security/" target="_blank" rel="noopener noreferrer" class="dropdown__link">Security</a></li><li><a href="https://www.apache.org/foundation/sponsorship.html" target="_blank" rel="noopener noreferrer" class="dropdown__link">Sponsorship</a></li><li><a href="https://www.apache.org/foundation/policies/privacy.html" target="_blank" rel="noopener noreferrer" class="dropdown__link">Privacy</a></li><li><a href="https://www.apache.org/foundation/thanks.html" target="_blank" rel="noopener noreferrer" class="dropdown__link">Thanks</a></li></ul></div></div><div class="navbar__items navbar__items--right"><div class="navbar__item dropdown dropdown--hoverable dropdown--right"><a class="navbar__link">Doc</a><ul class="dropdown__menu"><li><a class="dropdown__link" href="/docs/1.1.3/introduction">Next(1.1.3)</a></li><li><a class="dropdown__link" href="/docs/latest/introduction">1.1.2</a></li><li><a class="dropdown__link" href="/docs/1.1.1/introduction">1.1.1</a></li><li><a class="dropdown__link" href="/docs/1.1.0/introduction">1.1.0</a></li><li><a class="dropdown__link" href="/docs/1.0.3/introduction">1.0.3</a></li><li><a class="dropdown__link" href="/docs/1.0.2/introduction">1.0.2</a></li><li><a class="dropdown__link" href="/docs/0.11.0/introduction">0.11.0</a></li><li><a class="dropdown__link" href="/versions">All Version</a></li></ul></div><a href="https://github.com/apache/incubator-linkis" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link header-github-link" aria-label="GitHub"></a><div class="navbar__item dropdown dropdown--hoverable dropdown--right"><a href="#" class="navbar__link"><span><svg t="1631348384596" class="iconLanguage_EbrZ" viewBox="0 0 1024 1024" version="1.1" p-id="557" width="20" height="20"><path d="M547.797333 638.208l-104.405333-103.168 1.237333-1.28a720.170667 720.170667 0 0 0 152.490667-268.373333h120.448V183.082667h-287.744V100.906667H347.605333v82.218666H59.818667V265.386667h459.178666a648.234667 648.234667 0 0 1-130.304 219.946666 643.242667 643.242667 0 0 1-94.976-137.728H211.541333a722.048 722.048 0 0 0 122.453334 187.434667l-209.194667 206.378667 58.368 58.368 205.525333-205.525334 127.872 127.829334 31.232-83.84m231.424-208.426667h-82.218666l-184.96 493.312h82.218666l46.037334-123.306667h195.242666l46.464 123.306667h82.218667l-185.002667-493.312m-107.690666 287.744l66.56-178.005333 66.602666 178.005333z" fill="currentColor" p-id="558"></path></svg><span>English</span></span></a><ul class="dropdown__menu"><li><a href="/community/how-to-write-unit-test-code" target="_self" rel="noopener noreferrer" class="dropdown__link dropdown__link--active" style="text-transform:capitalize">English</a></li><li><a href="/zh-CN/community/how-to-write-unit-test-code" target="_self" rel="noopener noreferrer" class="dropdown__link" style="text-transform:capitalize">简体中文</a></li></ul></div><div class="searchBox_Bc3W"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"></span></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div class="main-wrapper docs-wrapper docs-doc-page"><div class="docPage_lDyR"><button class="clean-btn backToTopButton_i9tI" type="button"><svg viewBox="0 0 24 24" width="28"><path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z" fill="currentColor"></path></svg></button><aside class="docSidebarContainer_0YBq"><div class="sidebar_a3j0"><nav class="menu thin-scrollbar menu_cyFh menuWithAnnouncementBar_+O1J"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link menu__list-item"><a class="menu__link" href="/community/how-to-subscribe">How to Subscribe</a></li><li class="theme-doc-sidebar-item-link menu__list-item"><a class="menu__link" href="/community/how-to-email">How to Use Email List</a></li><li class="theme-doc-sidebar-item-link menu__list-item"><a class="menu__link" href="/community/how-to-contribute">How to Participate in Project Contribution</a></li><li class="theme-doc-sidebar-item-link menu__list-item"><a class="menu__link" href="/community/how-to-contribute-to-website">How to Participate in the Official Website Contribution</a></li><li class="theme-doc-sidebar-item-link menu__list-item"><a class="menu__link" href="/community/how-to-participate-in-developer-meetings">How to Participate in Developer Meetings</a></li><li class="theme-doc-sidebar-item-link menu__list-item"><a class="menu__link" href="/community/how-to-release">How to Release</a></li><li class="theme-doc-sidebar-item-link menu__list-item"><a class="menu__link" href="/community/how-to-verify">How to Verify</a></li><li class="theme-doc-sidebar-item-link menu__list-item"><a class="menu__link" href="/community/security">Security</a></li><li class="theme-doc-sidebar-item-link menu__list-item"><a class="menu__link" href="/community/apache-product-name-usage-guide">Apache Product Name Usage Guide</a></li><li class="theme-doc-sidebar-item-link menu__list-item"><a class="menu__link" href="/community/how-to-vote-a-committer-ppmc">How to Vote New Committer/PPMC</a></li><li class="theme-doc-sidebar-item-link menu__list-item"><a class="menu__link" href="/community/how-to-sign-apache-icla">ICLA Signing Process</a></li><li class="theme-doc-sidebar-item-link menu__list-item"><a class="menu__link" href="/community/ppmc-related-permission-configuration">PPMC/Committer Related Permission Configuration</a></li><li class="theme-doc-sidebar-item-category menu__list-item menu__list-item--collapsed"><a class="menu__link menu__link--sublist" href="#">Development Specification</a></li><li class="theme-doc-sidebar-item-link menu__list-item"><a class="menu__link menu__link--active" aria-current="page" href="/community/how-to-write-unit-test-code">How to Write Unit Test Code</a></li><li class="theme-doc-sidebar-item-link menu__list-item"><a class="menu__link" href="/community/microservice-division">Division of Microservices</a></li><li class="theme-doc-sidebar-item-link menu__list-item"><a class="menu__link" href="/community/site-map">sitemap</a></li></ul></nav></div></aside><main class="docMainContainer_r8cw"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_zHA2"><div class="docItemContainer_oiyr"><article><div class="tocCollapsible_aw-L theme-doc-toc-mobile tocMobile_Tx6Y"><button type="button" class="clean-btn tocCollapsibleButton_zr6a">On this page</button></div><div class="theme-doc-markdown markdown"><header><h1>How to Write Unit Test Code</h1></header><h2><a aria-hidden="true" tabindex="-1" class="anchor anchor__h2 anchorWithStickyNavbar_y2LR" id="frame-selection"></a>Frame Selection<a class="hash-link" href="#frame-selection" title="Direct link to heading">#</a></h2><p>Junit5 + mockito + Jacobo + H2 local database</p><p>Idea enhancement plugin </p><ul><li>JUnitGenerator V2. 0 standard module for generating test cases</li><li>Create the allnewset object and set the default value for allnewset</li><li>The association mapping between mybatisx ADO and mapper is easy to view</li></ul><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithStickyNavbar_y2LR" id="configure-the-template-of-junit-in-idea"></a>Configure the Template of JUnit in Idea<a class="hash-link" href="#configure-the-template-of-junit-in-idea" title="Direct link to heading">#</a></h3><div class="codeBlockContainer_J+bg"><div class="codeBlockContent_csEI properties"><pre tabindex="0" class="prism-code language-properties codeBlock_rtdJ thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block">
</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">######################################################################################## </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## Available variables: </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## $entryList.methodList - List of method composites </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## $entryList.privateMethodList - List of private method composites </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## $entryList.fieldList - ArrayList of class scope field names </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## $entryList.className - class name </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## $entryList.packageName - package name </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## $today - Todays date in MM/dd/yyyy format </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## MethodComposite variables: </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## $method.name - Method Name </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## $method.signature - Full method signature in String form </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## $method.reflectionCode - list of strings representing commented out reflection code to access method (Private Methods) </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## $method.paramNames - List of Strings representing the method&#x27;s parameters&#x27; names </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## $method.paramClasses - List of Strings representing the method&#x27;s parameters&#x27; classes </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## You can configure the output class name using &quot;testClass&quot; variable below. </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## Here are some examples: </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## Test${entry.ClassName} - will produce TestSomeClass </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## ${entry.className}Test - will produce SomeClassTest </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">######################################################################################## </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## title case </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">#macro (cap $strIn)$strIn.valueOf($strIn.charAt(0)).toUpperCase()$strIn.substring(1)#end </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## Initial lowercase custom down</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">#macro (down $strIn)$strIn.valueOf($strIn.charAt(0)).toLowerCase()$strIn.substring(1)#end</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">## Iterate through the list and generate testcase for every entry. </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">#foreach ($entry in $entryList) </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">#set( $testClass=&quot;${entry.className}Test&quot;) </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">##</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block">
</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">/*</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * Licensed to the Apache Software Foundation (ASF) under one or more</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * contributor license agreements. See the NOTICE file distributed with</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * this work for additional information regarding copyright ownership.</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * The ASF licenses this file to You under the Apache License, Version 2.0</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * (the &quot;License&quot;); you may not use this file except in compliance with</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * the License. You may obtain a copy of the License at</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> *</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * http://www.apache.org/licenses/LICENSE-2.0</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> *</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * Unless required by applicable law or agreed to in writing, software</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * See the License for the specific language governing permissions and</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * limitations under the License.</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> */</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block">
</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">package $entry.packageName; </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">import org.junit.jupiter.api.AfterEach;</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">import org.junit.jupiter.api.BeforeEach;</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">import org.junit.jupiter.api.DisplayName;</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">import org.junit.jupiter.api.Test;</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">import org.springframework.beans.factory.annotation.Autowired;</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block">
</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">/** </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * ${entry.className} Tester</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">*/ </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">public class $testClass { </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> @Autowired</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> private ${entry.className} #down(${entry.className});</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> @BeforeEach</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> @DisplayName(&quot;Each unit test method is executed once before execution&quot;)</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> public void before() throws Exception {</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> @AfterEach</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> @DisplayName(&quot;Each unit test method is executed once before execution&quot;)</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> public void after() throws Exception {</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">#foreach($method in $entry.methodList) </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> @Test</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> @DisplayName(&quot;Method description: ...&quot;)</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> public void test#cap(${method.name})() throws Exception { </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> //TODO: Test goes here... </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> } </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">#end </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">#foreach($method in $entry.privateMethodList) </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block">
</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> @Test</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> @DisplayName(&quot;Method description: ...&quot;)</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> public void test#cap(${method.name})() throws Exception { </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> //TODO: Test goes here... </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> #foreach($string in $method.reflectionCode) </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> $string </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> #end </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> } </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">#end </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">} </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">#end</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block">
</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_M3SB clean-btn">Copy</button></div></div><p><img src="https://user-images.githubusercontent.com/29391030/155080741-7e6b89db-0ee6-48e1-a858-4123d5bbf2f0.png" alt="test-0"></p><ol><li><p>Configure test class generation path </p><p>Original configuration: ${sourcepath}/test/${package}/${filename}<br>
<!-- -->Modified configuration: ${sourcepath}/..//test/java/${PACKAGE}/${FILENAME} </p><p>As shown in the figure:<br>
<img src="https://user-images.githubusercontent.com/29391030/155080336-476feba6-2790-43b5-a572-ee0aa6a9586f.png" alt="test-1"></p></li><li><p>Select class -&gt; right click -&gt; generate -&gt; JUnit test to generate a test class</p><p><img src="https://user-images.githubusercontent.com/29391030/155080650-4fa68c66-5d7c-4e9f-ba63-0c7fc62d9df2.png" alt="test-2"></p></li></ol><h2><a aria-hidden="true" tabindex="-1" class="anchor anchor__h2 anchorWithStickyNavbar_y2LR" id="unit-test-criteria"></a>Unit Test Criteria<a class="hash-link" href="#unit-test-criteria" title="Direct link to heading">#</a></h2><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithStickyNavbar_y2LR" id="catalogue-and-naming-citeria"></a>Catalogue And Naming Citeria<a class="hash-link" href="#catalogue-and-naming-citeria" title="Direct link to heading">#</a></h3><ul><li><ol><li>Unit test code directory
It must be written in the following project directory: src/test/java. It is not allowed to write in the business code directory.<br>Note: this directory will be skipped during source code compilation, while the unit test framework scans this directory by default. The test configuration file must be placed under the src/test/resources file</li></ol></li><li><ol start="2"><li>The package name of the test class should be consistent with the package name of the tested class<br>Example:<br>Business class: src/main/java/org/apache/linkis/jobhistory/dao/JobDetailMapper.java<br>Corresponding test class:src/main/java/org/apache/linkis/jobhistory/dao/JobDetailMapperTest java </li></ol></li><li><ol start="3"><li>Naming and definition specification of test class: use test as the suffix of class name<br>The test class is named as follows:<br>Tested business + test, tested interface + test, tested class + test </li></ol></li><li><ol start="4"><li>Specification for naming and defining test cases: use test as the prefix of method names
The naming rule of test cases is: test + method name. Avoid using names that have no meaning in test1 and test2. Secondly, necessary function and method annotations are required.</li></ol></li></ul><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithStickyNavbar_y2LR" id="unit-coding-specifications"></a>Unit Coding Specifications<a class="hash-link" href="#unit-coding-specifications" title="Direct link to heading">#</a></h3><ul><li><ol><li>System is not allowed to be used in unit test Out for human flesh verification, or if judgment for verification (log can be used for Key log output). Assertion assert must be used for verification.</li></ol></li><li><ol start="2"><li>Maintain the independence of unit testing. In order to ensure that unit tests are stable, reliable and easy to maintain, unit test cases must not call each other or rely on the order of execution.
Counterexample: method2 needs to rely on the execution of method1 and take the execution result as the input of method2</li></ol></li><li><ol start="3"><li>Unit tests must be repeatable and not affected by the external environment.<br>Note: unit tests are usually put into continuous integration. Unit tests will be executed every time there is code check in. If the single test depends on the external environment (network, service, middleware, etc.), it is easy to lead to the unavailability of the continuous integration mechanism.<br>Positive example: in order not to be affected by the external environment, it is required to change the relevant dependencies of the tested class into injection when designing the code, and inject a local (memory) implementation or mock implementation with a dependency injection framework such as spring during testing.</li></ol></li><li><ol start="4"><li>Incremental code ensures that the unit test passes.
Note: the new code must supplement the unit test. If the new code affects the original unit test, please correct it</li></ol></li><li><ol start="5"><li>For unit testing, it is necessary to ensure that the test granularity is small enough to help accurately locate the problem. Single test granularity is generally at the method level (very few scenarios such as tool classes or enumeration classes can be at the class level).<br>Note: only with small test granularity can we locate the error location as soon as possible. Single test is not responsible for checking cross class or cross system interaction logic, which is the field of integration testing.</li></ol></li></ul><h2><a aria-hidden="true" tabindex="-1" class="anchor anchor__h2 anchorWithStickyNavbar_y2LR" id="use-of-assertions"></a>Use of Assertions<a class="hash-link" href="#use-of-assertions" title="Direct link to heading">#</a></h2><div class="codeBlockContainer_J+bg"><div class="codeBlockContent_csEI"><pre tabindex="0" class="prism-code language-undefined codeBlock_rtdJ thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#F8F8F2"><span class="token plain">The result verification of all test cases must use the assertion pattern </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> use Assertions.assertEquals</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Assertions.assertEquals(expectedJobDetail, actualJobDetail)</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">The assertions assertion of junit5 is preferred, and the assertions of assertij are allowed in very few scenarios </span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Comparison of objects before/after updating common scene databases</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Asserting the usingrecursive comparison pattern using assertj&#x27;s assertThat</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Assertions.assertThat(actualObject).usingRecursiveComparison().isEqualTo(expectedObject);</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_M3SB clean-btn">Copy</button></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithStickyNavbar_y2LR" id="junit5-general-assertion"></a>Junit5 General Assertion<a class="hash-link" href="#junit5-general-assertion" title="Direct link to heading">#</a></h3><table><thead><tr><th>Method</th><th>description</th><th>remarks</th></tr></thead><tbody><tr><td>Assertequals</td><td>judge whether two objects or two original types are equal</td><td></td></tr><tr><td>Assertnotequals</td><td>judge whether two objects or two original types are not equal</td><td></td></tr><tr><td>Asserttrue</td><td>judge whether the given Boolean value is true</td><td></td></tr><tr><td>Assertfalse</td><td>judge whether the given Boolean value is false</td><td></td></tr><tr><td>AssertNull</td><td>judge whether the given object reference is null</td><td></td></tr><tr><td>AssertNotNull</td><td>judge whether the given object reference is not null</td><td></td></tr><tr><td>Assert all</td><td>multiple judgment logics are processed together. As long as one error is reported, the overall test will fail</td><td></td></tr></tbody></table><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithStickyNavbar_y2LR" id="junit5-combined-assertion-and-exception-assertion"></a>Junit5 Combined Assertion and Exception Assertion<a class="hash-link" href="#junit5-combined-assertion-and-exception-assertion" title="Direct link to heading">#</a></h3><p><strong>Composite assertion</strong>
The assertall method can process multiple judgment logics together. As long as one error is reported, the overall test will fail:</p><div class="codeBlockContainer_J+bg"><div class="codeBlockContent_csEI java"><pre tabindex="0" class="prism-code language-java codeBlock_rtdJ thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#F8F8F2"><span class="token plain"> @Test</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> @DisplayName(&quot;assert all&quot;)</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> public void all() {</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> //Multiple judgments are executed together. Only when all judgments are passed can they be considered as passed</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> assertAll(&quot;Math&quot;,</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> () -&gt; assertEquals(2, 1 + 1),</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> () -&gt; assertTrue(1 &gt; 0)</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> );</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_M3SB clean-btn">Copy</button></div></div><p><strong>Exception assertion</strong></p><p>Assertions. The assertthrows method is used to test whether the executable instance throws an exception of the specified type when executing the execute method;<br>
<!-- -->If the execute method does not throw an exception during execution, or the exception thrown is inconsistent with the expected type, the test will fail;<br>
<!-- -->Example: </p><div class="codeBlockContainer_J+bg"><div class="codeBlockContent_csEI java"><pre tabindex="0" class="prism-code language-java codeBlock_rtdJ thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#F8F8F2"><span class="token plain"> @Test</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> @DisplayName(&quot;Assertion of exception&quot;)</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> void exceptionTesting() {</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> // When the execute method is executed, if an exception is thrown and the type of the exception is the first parameter of assertthrows (here is arithmeticexception. Class)</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> // The return value is an instance of an exception</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Exception exception = assertThrows(ArithmeticException.class, () -&gt; Math.floorDiv(1,0));</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> log.info(&quot;assertThrows pass,return instance:{}&quot;, exception.getMessage());</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_M3SB clean-btn">Copy</button></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithStickyNavbar_y2LR" id="assertion-usage-criteria"></a>Assertion Usage Criteria<a class="hash-link" href="#assertion-usage-criteria" title="Direct link to heading">#</a></h3><p><strong>Object instance equality assertion</strong></p><ol><li>Is it the same object instance</li></ol><div class="codeBlockContainer_J+bg"><div class="codeBlockContent_csEI html"><pre tabindex="0" class="prism-code language-html codeBlock_rtdJ thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Use junitd&#x27;s assertions assertEquals</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Assertions.assertEquals(expectedJobDetail, actualJobDetail)</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_M3SB clean-btn">Copy</button></div></div><p>Not the same instance, but whether the attribute values of the comparison instance are exactly equal<br>
<!-- -->AssertJ</p><div class="codeBlockContainer_J+bg"><div class="codeBlockContent_csEI html"><pre tabindex="0" class="prism-code language-html codeBlock_rtdJ thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Comparison of objects before/after updating common scene databases</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Asserting the usingrecursive comparison pattern using assertj&#x27;s assertthat</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Assertions. assertThat(actualObject). usingRecursiveComparison(). isEqualTo(expectedObject);</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_M3SB clean-btn">Copy</button></div></div><ol start="2"><li>Assertion of set results such as list
The size of the result set needs to be asserted
Scope or specific size
Each object in the result set needs assertion, which is recommended to be used in combination with the predicate of stream mode
Example:</li></ol><div class="codeBlockContainer_J+bg"><div class="codeBlockContent_csEI java"><pre tabindex="0" class="prism-code language-java codeBlock_rtdJ thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#F8F8F2"><span class="token plain">ArrayList&lt;JobRespProtocol&gt; jobRespProtocolArrayList=service. batchChange(jobDetailReqBatchUpdate);</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">//List is matched with the predicate of stream for assertion judgment</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Predicate&lt;JobRespProtocol&gt; statusPrecate = e -&gt; e.getStatus()==0;</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">assertEquals(2, jobRespProtocolArrayList.size());</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">assertTrue(jobRespProtocolArrayList.stream(). anyMatch(statusPrecate));</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_M3SB clean-btn">Copy</button></div></div><h2><a aria-hidden="true" tabindex="-1" class="anchor anchor__h2 anchorWithStickyNavbar_y2LR" id="compilation-of-unit-test"></a>Compilation of Unit Test<a class="hash-link" href="#compilation-of-unit-test" title="Direct link to heading">#</a></h2><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithStickyNavbar_y2LR" id="class-division"></a>Class Division<a class="hash-link" href="#class-division" title="Direct link to heading">#</a></h3><p>It can be roughly classified according to the major functions of the class</p><p>-The controller of the HTTP service provided by the controller cooperates with mockmvc for unit testing
-Service layer of service business logic code
-Dao and Dao layer of database operation
-Util tool function class is a common function tool
-Exception class is a custom exception class
-Enum class
-Entity class is used for DB interaction and parameter VO object and other entity classes processed by methods (if there are other user-defined functions besides normal get set, unit test is required)</p><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithStickyNavbar_y2LR" id="unit-test-of-controller-class"></a>Unit Test of Controller class<a class="hash-link" href="#unit-test-of-controller-class" title="Direct link to heading">#</a></h3><p>Using mockmvc</p><p>It mainly verifies the requestmethod method of interface request, basic parameters and expected return results.<br>
<!-- -->Main scenarios: scenarios with and without unnecessary parameters are abnormal </p><div class="codeBlockContainer_J+bg"><div class="codeBlockContent_csEI java"><pre tabindex="0" class="prism-code language-java codeBlock_rtdJ thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#F8F8F2"><span class="token plain"> @Test</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> public void testList() throws Exception {</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> //Bring unnecessary parameters</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> MultiValueMap&lt;String, String&gt; paramsMap = new LinkedMultiValueMap&lt;&gt;();</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> paramsMap.add(&quot;startDate&quot;, String.valueOf(System.currentTimeMillis()));</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> MvcResult mvcResult = mockMvc.perform(get(&quot;/jobhistory/list&quot;)</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> .params(paramsMap))</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> .andExpect(status().isOk())</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> .andExpect(content().contentType(MediaType.APPLICATION_JSON))</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> .andReturn();</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block">
</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Message res = JsonUtils.jackson().readValue(mvcResult.getResponse().getContentAsString(), Message.class);</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> assertEquals(res.getStatus(), MessageStatus.SUCCESS());</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> logger.info(mvcResult.getResponse().getContentAsString());</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block">
</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> //Without unnecessary parameters</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> mvcResult = mockMvc.perform(get(&quot;/jobhistory/list&quot;))</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> .andExpect(status().isOk())</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> .andExpect(content().contentType(MediaType.APPLICATION_JSON))</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> .andReturn();</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block">
</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> res = JsonUtils.jackson().readValue(mvcResult.getResponse().getContentAsString(), Message.class);</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> assertEquals(res.getStatus(), MessageStatus.SUCCESS());</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block">
</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> logger.info(mvcResult.getResponse().getContentAsString());</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block">
</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_M3SB clean-btn">Copy</button></div></div><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithStickyNavbar_y2LR" id="unit-test-of-server-class"></a>Unit Test of Server class<a class="hash-link" href="#unit-test-of-server-class" title="Direct link to heading">#</a></h3><p> //todo</p><h3><a aria-hidden="true" tabindex="-1" class="anchor anchor__h3 anchorWithStickyNavbar_y2LR" id="unit-test-of-dao-class"></a>Unit Test of Dao class<a class="hash-link" href="#unit-test-of-dao-class" title="Direct link to heading">#</a></h3><p>Use H2 database, application. In the configuration file In properties, you need to configure the basic information of H2 database and the relevant path information of mybatis </p><div class="codeBlockContainer_J+bg"><div class="codeBlockContent_csEI properties"><pre tabindex="0" class="prism-code language-properties codeBlock_rtdJ thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_1zSZ"><span class="token-line" style="color:#F8F8F2"><span class="token plain">#h2 database configuration</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.driver-class-name=org.h2.Driver</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"># Script to connect database</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.url=jdbc:h2:mem:test;MODE=MySQL;DB_CLOSE_DELAY=-1;DATABASE_TO_LOWER=true</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">#Script to initialize database tables</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.schema=classpath:create.sql</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">#Script to initialize data for database tables</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.data=classpath:data.sql</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.username=sa</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.password=</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.hikari.connection-test-query=select 1</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.hikari.minimum-idle=5</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.hikari.auto-commit=true</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.hikari.validation-timeout=3000</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.hikari.pool-name=linkis-test</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.hikari.maximum-pool-size=50</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.hikari.connection-timeout=30000</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.hikari.idle-timeout=600000</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.hikari.leak-detection-threshold=0</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">spring.datasource.hikari.initialization-fail-timeout=1</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block">
</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">#配置mybatis-plus的mapper信息 因为使用的是mybatis-plus,使用mybatis-plus</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">mybatis-plus.mapper-locations=classpath:org/apache/linkis/jobhistory/dao/impl/JobDetailMapper.xml,classpath:org/apache/linkis/jobhistory/dao/impl/JobHistoryMapper.xml</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">mybatis-plus.type-aliases-package=org.apache.linkis.jobhistory.entity</span></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl</span></span></code></pre><button type="button" aria-label="Copy code to clipboard" class="copyButton_M3SB clean-btn">Copy</button></div></div><p>List is configured with predicate of stream to make assertion judgment and write specification</p><ol><li>Use @Transactional and @Rollback to realize data rollback and avoid data pollution</li><li>Each DaoTest should have a public method for creating and initializing data (or the way of importing data CSV) to prepare data. For related queries, updates, deletions and other operations, the public method should be called first to prepare data</li><li>Create test data. If an attribute value is a self increasing ID, it should not be assigned</li><li>The test data created shall be consistent with the actual sample data as far as possible</li><li>When updating the data test, if the field allows, please prefix it with &#x27;modify original value&#x27;</li></ol></div><footer class="theme-doc-footer docusaurus-mt-lg"><div class="theme-doc-footer-edit-meta-row row"><div class="col"><a href="https://github.com/apache/incubator-linkis-website/edit/dev/community/how-to-write-unit-test-code.md" target="_blank" rel="noreferrer noopener" class="theme-edit-this-page"><svg fill="currentColor" height="20" width="20" viewBox="0 0 40 40" class="iconEdit_mS5F" aria-hidden="true"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>Edit this page</a></div><div class="col lastUpdated_mt2f"></div></div></footer></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages navigation"><div class="pagination-nav__item"><a class="pagination-nav__link" href="/community/development_specification/release-notes"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">« <!-- -->Release-Notes Writing Specification</div></a></div><div class="pagination-nav__item pagination-nav__item--next"><a class="pagination-nav__link" href="/community/microservice-division"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Division of Microservices<!-- --> »</div></a></div></nav></div></div><div class="col col--3"><div class="tableOfContents_vrFS thin-scrollbar"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#frame-selection" class="table-of-contents__link">Frame Selection</a><ul><li><a href="#configure-the-template-of-junit-in-idea" class="table-of-contents__link">Configure the Template of JUnit in Idea</a></li></ul></li><li><a href="#unit-test-criteria" class="table-of-contents__link">Unit Test Criteria</a><ul><li><a href="#catalogue-and-naming-citeria" class="table-of-contents__link">Catalogue And Naming Citeria</a></li><li><a href="#unit-coding-specifications" class="table-of-contents__link">Unit Coding Specifications</a></li></ul></li><li><a href="#use-of-assertions" class="table-of-contents__link">Use of Assertions</a><ul><li><a href="#junit5-general-assertion" class="table-of-contents__link">Junit5 General Assertion</a></li><li><a href="#junit5-combined-assertion-and-exception-assertion" class="table-of-contents__link">Junit5 Combined Assertion and Exception Assertion</a></li><li><a href="#assertion-usage-criteria" class="table-of-contents__link">Assertion Usage Criteria</a></li></ul></li><li><a href="#compilation-of-unit-test" class="table-of-contents__link">Compilation of Unit Test</a><ul><li><a href="#class-division" class="table-of-contents__link">Class Division</a></li><li><a href="#unit-test-of-controller-class" class="table-of-contents__link">Unit Test of Controller class</a></li><li><a href="#unit-test-of-server-class" class="table-of-contents__link">Unit Test of Server class</a></li><li><a href="#unit-test-of-dao-class" class="table-of-contents__link">Unit Test of Dao class</a></li></ul></li></ul></div></div></div></div></main></div></div><footer class="footer"><div class="container"><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Linkis</div><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/docs/latest/introduction">Document</a></li><li class="footer__item"><a class="footer__link-item" href="/faq/main">FAQ</a></li><li class="footer__item"><a href="https://github.com/apache/incubator-linkis/releases" target="_blank" rel="noopener noreferrer" class="footer__link-item"><span>Releases<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_wgqa"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></span></a></li></ul></div><div class="col footer__col"><div class="footer__title">Community</div><ul class="footer__items"><li class="footer__item"><a href="https://github.com/apache/incubator-linkis" target="_blank" rel="noopener noreferrer" class="footer__link-item"><span>GitHub<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_wgqa"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></span></a></li><li class="footer__item"><a href="https://github.com/apache/incubator-linkis/issues" target="_blank" rel="noopener noreferrer" class="footer__link-item"><span>Issue Tracker<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_wgqa"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></span></a></li><li class="footer__item"><a href="https://github.com/apache/incubator-linkis/pulls" target="_blank" rel="noopener noreferrer" class="footer__link-item"><span>Pull Requests<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_wgqa"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></span></a></li></ul></div><div class="col footer__col"><div class="footer__title">Subscribe Mailing List</div><ul class="footer__items"><li class="footer__item"><a class="footer__link-item" href="/community/how-to-subscribe">How to Subscribe</a></li><li class="footer__item"><a href="mailto:dev-subscribe@linkis.apache.org" target="_blank" rel="noopener noreferrer" class="footer__link-item"><span>Subscribe Mail<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_wgqa"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></span></a></li><li class="footer__item"><a href="https://lists.apache.org/list.html?dev@linkis.apache.org" target="_blank" rel="noopener noreferrer" class="footer__link-item"><span>Mail Archive<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_wgqa"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></span></a></li></ul></div></div><div class="footer__bottom text--center"><div class="footer__copyright"><div><img style="height:50px" alt="Apache Software Foundation" src="/img/incubator-logo.svg"><p style="color: #999999; padding: 0 20px 30px;font-weight:400;text-align:left">Apache Linkis is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF.</p><p></p>
<p style="padding: 0 20px 30px;color: #999999;font-weight: 400;"> Copyright © 2022 The Apache Software Foundation. Licensed under the Apache License, Version 2.0. Apache Linkis, Apache Incubator, Apache, the Apache feather logo, the Apache Linkis logo and the Apache Incubator project logo are trademarks of The Apache Software Foundation.</p>
<div></div></div></div></div></div></footer></div>
<script src="/assets/js/runtime~main.a4c60f50.js"></script>
<script src="/assets/js/main.42471b13.js"></script>
</body>
</html>