Maison > interface Web > js tutoriel > le corps du texte

Introduction aux tests unitaires angulaires à l'aide de Jasmine

青灯夜游
Libérer: 2020-08-26 10:19:20
avant
2742 Les gens l'ont consulté
<p>Cet article vous expliquera comment utiliser Jasmine pour les tests unitaires angulaires ? Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il sera utile à tout le monde. </p> <p><img src="https://img.php.cn/upload/article/000/000/024/5f408f91953d2985.jpg" alt="Introduction aux tests unitaires angulaires à l'aide de Jasmine" ></p> <p>Ce qui suit est préparé par moi en supposant que ceux qui ont rarement ou pas écrit de tests unitaires peuvent donc expliquer de nombreux problèmes conceptuels en langue vernaculaire et utiliseront également Jasmine. pour y répondre, des méthodes sont expliquées. </p> <p><span style="font-size: 20px;"><strong>1. Concept</strong></span></p> <p><span style="font-size: 18px;"><strong>Suite de tests</strong></span></p> <p>Suite de tests, Même une classe simple aura plusieurs cas de test, donc la collection de ces cas de test sous une seule catégorie est appelée <strong>Test Suite</strong>. </p> <p> Dans Jasmine, il est représenté par la fonction globale <code>describe</code> Son premier paramètre de chaîne est utilisé pour représenter le nom ou le titre de la Suite, et le deuxième paramètre de méthode consiste à implémenter le code de la Suite. </p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">describe(&#39;test suite name&#39;, () => { });</pre><div class="contentsignin">Copier après la connexion</div></div><p><span style="font-size: 18px;"><strong>Specs</strong></span></p><p>Une spécification est équivalente à un scénario de test, qui est le corps spécifique de code que nous implémentons pour tester. </p><p>Jasmine utilise la fonction globale <code>it</code> pour le représenter. Semblable à <code>describe</code>, elle a deux paramètres : chaîne et méthode. </p><p> Chaque spécification comprend plusieurs attentes pour tester le code qui doit être testé Tant que le résultat d'une attente est <code>false</code>, cela signifie que le scénario de test est dans un état d'échec. </p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">describe(&#39;demo test&#39;, () => { const VALUE = true; it(&#39;should be true&#39;, () => { expect(VALUE).toBe(VALUE); }) });</pre><div class="contentsignin">Copier après la connexion</div></div><p><span style="font-size: 18px;"><strong>Attentes</strong></span></p><p>L'assertion, représentée par la <code>expect</code> fonction globale, ne reçoit qu'une <strong>valeur réelle< qui représente le test 🎜>, et doit être mis en correspondance avec Matcher pour représenter la </strong>valeur attendue<strong>. </strong></p><p><span style="font-size: 20px;">2. Méthodes courantes<strong></strong></span></p><p><span style="font-size: 18px;">Matchers<strong></strong></span></p>Opération de correspondance d'assertions , comparez la valeur réelle avec la valeur attendue et informez Jasmine du résultat. Enfin, Jasmine déterminera si cette spécification réussit ou échoue. <p></p>Jasmine fournit une API très riche, certains Matchers couramment utilisés : <p></p><ul><li> est équivalent à <code>toBe()</code><code>===</code></li>toNotBe() est équivalent à <li><code>!==</code> </li>toBeDefined() est équivalent à<li><code>!== undefined</code></li>toBeUndefined() est équivalent à<li><code>=== undefined</code></li>toBeNull() est équivalent à<li><code>=== null</code></li>toBeTruthy() est équivalent à<li><code>!!obj</code></li>toBeFalsy() est équivalent à<li><code>!obj</code></li>toBeLessThan() est équivalent à<li><code><</code></li>toBeGreaterThan() est équivalent à<li><code>></code></li>toEqual() est équivalent à<li><code>==</code></li>toNotEqual() est équivalent à <li><code>!=</code></li>toContain() est équivalent à <li><code>indexOf</code></li>toBeCloseTo() Définissez la précision lors de la comparaison des valeurs numériques, arrondissez d'abord puis comparez . <li></li>toHaveBeenCalled() vérifie si la fonction a été appelée <li></li>toHaveBeenCalledWith() vérifie si les paramètres entrants ont été appelés en tant que paramètres <li></li>toMatch() est équivalent à <li> <code>new RegExp().test()</code> </li>toNotMatch() est équivalent à <li><code>!new RegExp().test()</code></li>toThrow() pour vérifier si la fonction générera une erreur <li></li></ul> Ces API précédemment utilisées <p>. pour indiquer un jugement de valeur négatif. <code>not</code><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">expect(true).not.toBe(false);</pre><div class="contentsignin">Copier après la connexion</div></div></p>Ces Matchers peuvent presque répondre à nos besoins quotidiens. Bien sûr, vous pouvez également personnaliser votre propre Matcher pour répondre à des besoins particuliers. <p></p><p><span style="font-size: 18px;">Configuration et démontage<strong></strong></span></p>Un code de test général est très important, nous pouvons donc mettre ces codes de configuration et de démontage répétés dans le <🎜 correspondant > et <p> sont dans la fonction globale. <code>beforeEach</code><code>afterEach</code></p> signifie avant l'exécution de chaque spécification, et vice versa. <p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">describe(&#39;demo test&#39;, () => { let val: number = 0; beforeEach(() => { val = 1; }); it(&#39;should be true&#39;, () => { expect(val).toBe(1); }); it(&#39;should be false&#39;, () => { expect(val).not.toBe(0); }); });</pre><div class="contentsignin">Copier après la connexion</div></div><code>beforeEach</code></p><p>Partage des données<span style="font-size: 18px;"><strong></strong></span>Comme dans l'exemple ci-dessus, on peut définir les variables correspondantes au début de chaque fichier de test, </p> , De cette façon, chacun <p> peut les partager en interne. <code>describe</code><code>it</code>Bien entendu, chaque cycle d'exécution de la spécification sera accompagné d'un objet </p> vide jusqu'à ce qu'il soit effacé une fois l'exécution de la spécification terminée. Le partage de données peut également être effectué à l'aide de <p>. <code>this</code><code>this</code></p><p>Code imbriqué<span style="font-size: 18px;"><strong></strong></span>Parfois, lorsque nous testons un composant, le composant aura différents états pour afficher différents. Par conséquent, en utilisant un seul </p> à ce moment-là, cela aura l'air trop élégant. <p><code>describe</code> Par conséquent, l'imbrication </p> rendra le code de test et le rapport de test plus beaux. <p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">describe(&#39;AppComponent&#39;, () => { describe(&#39;Show User&#39;, () => { it(&#39;should be show panel.&#39;, () => {}); it(&#39;should be show avatar.&#39;, () => {}); }); describe(&#39;Hidden User&#39;, () => { it(&#39;should be hidden panel.&#39;, () => {}); }); });</pre><div class="contentsignin">Copier après la connexion</div></div><code>describe</code></p><p>Passer le bloc de code de test<span style="font-size: 18px;"><strong></strong></span>La demande est toujours timide, mais le code de test est finalement écrit, s'il est supprimé ? Non...</p><p>Les suites et les spécifications peuvent utiliser respectivement les fonctions globales </p> et <p> pour ignorer ces blocs de code de test. <code>xdescribe</code><code>xit</code></p><p>3. Coopérer avec l'ensemble d'outils angulaires<span style="font-size: 20px;"><strong></strong></span></p><p>Spy<span style="font-size: 18px;"><strong></strong><p><a href="https://img.php.cn/upload/article/000/000/024/5f45c5bc2de7d900.jpg" target="_blank">Angular</a>的自定义事件实在太普遍了,但为了测试这些自定义事件,因此监控事件是否正常被调用是非常重要。好在,<code>Spy</code> 可以用于监测函数是否被调用,这简直就是我们的好伙伴。</p><p>以下示例暂时无须理会,暂且体验一下:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">describe(&#39;AppComponent&#39;, () => { let fixture: ComponentFixture<TestComponent>; let context: TestComponent; beforeEach(() => { TestBed.configureTestingModule({ declarations: [TestComponent] }); fixture = TestBed.createComponent(TestComponent); context = fixture.componentInstance; // 监听onSelected方法 spyOn(context, &#39;onSelected&#39;); fixture.detectChanges(); }); it(&#39;should be called [selected] event.&#39;, () => { // 触发selected操作 // 断言是否被调用过 expect(context.onSelected).toHaveBeenCalled(); }); });</pre><div class="contentsignin">Copier après la connexion</div></div><p><span style="font-size: 18px;"><strong>异步支持</strong></span></p><p>首先,这里的异步是指带有 Observable 或 Promise 的异步行为,因此对于组件在调用某个 Service 来异步获取数据时的测试状态。</p><p>假设我们的待测试组件代码:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">export class AppComponent { constructor(private _user: UserService) {} query() { this._user.quer().subscribe(() => {}); } }</pre><div class="contentsignin">Copier après la connexion</div></div><p><strong>async</strong></p><p><code>async</code> 无任何参数与返回值,所有包裹代码块里的测试代码,可以通过调用 <code>whenStable()</code> 让<strong>所有待处理异步行为都完成后</strong>再进行回调;最后,再进行断言操作。</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">it(&#39;should be get user list (async)&#39;, async(() => { // call component.query(); fixture.whenStable().then(() => { fixture.detectChanges(); expect(true).toBe(true); }); }));</pre><div class="contentsignin">Copier après la connexion</div></div><p><strong>fakeAsync</strong></p><p>如果说 <code>async</code> 还需要回调才能进行断点让你受不了的话,那么 <code>fakeAsync</code> 可以解决这一点。</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false">it(&#39;should be get user list (async)&#39;, fakeAsync(() => { // call component.query(); tick(); fixture.detectChanges(); expect(true).toBe(true); }));</pre><div class="contentsignin">Copier après la connexion</div></div><p>这里只是将回调换成 <code>tick()</code>,怎么样,是不是很酷。</p><p><strong>Jasmine自带异步</strong></p><p>如前面所说的异步是指带有 Observable 或 Promise 的异步行为,而有时候我们有些东西是依赖 <code>setTimeout</code> 或者可能是需要外部订阅结果以后才能触发时怎么办呢?</p><p>可以使用 <code>done()</code> 方法。</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">it(&#39;async demo&#39;, (done: () => void) => { context.show().subscribe(res => { expect(true).toBe(true); done(); }); el.querySelected(&#39;xxx&#39;).click(); });</pre><div class="contentsignin">Copier après la connexion</div></div><p><span style="font-size: 20px;"><strong>四、结论</strong></span></p> <p>本章几乎所有的内容在Angular单元测试经常使用到的东西;特别是异步部分,三种不同异步方式并非共存的,而是需要根据具体业务而采用。否则,你会发现真TM难写单元测试。毕竟这是一个异步的世界。</p> <p>自此,我们算是为Angular写单元测试打下了基础。后续,将不会再对这类基础进行解释。</p> <p>happy coding!</p> <p>相关教程推荐:<a href="https://www.php.cn/course/list/20.html" target="_blank">angular教程</a></p>

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:segmentfault.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!