Reaksiyondaki sınıf bileşenlerini test etme


9

Bazı birim testleri deniyorum, sahte bir örnekle bir sanal alan oluşturdum https://codesandbox.io/s/wizardly-hooks-32w6l (gerçekte bir formum var)

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { number: 0 };    
  }

  handleSubmit = (number1, number2) => {
    this.setState({ number: this.handleMultiply(number1, number2) })
  }

  handleMultiply = (number1, number2) => {
    return number1 * number2
  }

  render() {
    const { number } = this.state;

    return (
      <div className="App">
        <form onSubmit={e => this.handleSubmit(3, 7)}>       
          <input type="submit" name="Submit" value="Multiply" />
        </form>
        <Table number={number} />
      </div>
    );
  }
}

export default App;

Benim ilk fikrim çarpma fonksiyonunu test etmeye çalışmaktı. Ve bunu yaptı, tabii ki işe yaramıyor

import App from "../src/App";

test("Multiply", function() {
  const expected = 21;
  const result = App.handleMultiply(3, 7);
  expect(result).toBe(expected);
});

alırım

_App.default.handleMultiply bir işlev değil

Yaklaşımım doğru mu? Evet ise, fonksiyonları nasıl test edebilirim? Aksi takdirde, dahili işlevler yerine bir kullanıcı açısından test etmeliyim (okuduğum budur)? Ekrandaki çıktıları test etmeli miyim (bunun makul olduğunu düşünmüyorum)?


2
Buna yanlış zihniyetle yaklaşıyorsunuz. Bunun yerine form gönderimini tetikleyin ve çarpma mantığı da dahil durumun uygun şekilde güncellendiğinden emin olun.
Alexander Staroselsky

@AlexanderStaroselsky tamam, teşekkür ederim, deneyeceğim ve takılırsam daha spesifik bir soru yapacağım
user3808307

@AlexanderStaroselsky, bir alt bileşendeki form ve üst öğedeki gönderme işleyicileri ne olur? Orada entegrasyon testleri yapmam gerekir mi?
user3808307

1
Bu bir fikir meselesi olabilir ama bunları kesinlikle ayrı ayrı test ederim. Çocuk için yapılan testler, gönderildiğinde üst kısımdan sahne ile geçen işlevi tetikler ve daha sonra da durumun beklediğiniz gibi işlediğini test etmek olacaktır. Ebeveyn için olayı tetiklerdim ve durumun doğru şekilde güncellendiğinden emin olurum.
Alexander Staroselsky

@AlexanderStaroselsky Teşekkür ederim
user3808307

Yanıtlar:


4

React Bileşeni örneğini almak için instance () yöntemini kullanabilirsiniz enzyme. Ardından, handleMultiplyyöntemi doğrudan çağırın ve bunun için iddiada bulunun. Ayrıca, handleMultiplyyöntemin bir yan etkisi veya çok karmaşık hesaplamaları varsa, bunun için basit bir alaycı dönüş değeri yapmanız gerekir. handleSubmitYöntem için izole bir test ortamı oluşturacaktır . Bu, handleSubmityöntemin, yöntemin gerçek uygulamasının dönüş değerine bağlı olmayacağı anlamına gelir handleMultiply.

Örneğin

app.jsx:

import React from 'react';
import { Table } from './table';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { number: 0 };
  }

  handleSubmit = (number1, number2) => {
    this.setState({ number: this.handleMultiply(number1, number2) });
  };

  handleMultiply = (number1, number2) => {
    return number1 * number2;
  };

  render() {
    const { number } = this.state;

    return (
      <div className="App">
        <form onSubmit={(e) => this.handleSubmit(3, 7)}>
          <input type="submit" name="Submit" value="Multiply" />
        </form>
        <Table number={number} />
      </div>
    );
  }
}

export default App;

table.jsx:

import React from 'react';

export const Table = ({ number: num }) => {
  return <div>table: {num}</div>;
};

app.test.jsx:

import App from './app';
import { shallow } from 'enzyme';

describe('59796928', () => {
  let wrapper;
  beforeEach(() => {
    wrapper = shallow(<App></App>);
  });
  describe('#handleSubmit', () => {
    it('should pass', () => {
      expect(wrapper.exists()).toBeTruthy();
      wrapper.find('form').simulate('submit');
      expect(wrapper.state()).toEqual({ number: 21 });
    });
  });
  describe('#handleMultiply', () => {
    it('should pass', () => {
      const comp = wrapper.instance();
      const actual = comp.handleMultiply(2, 10);
      expect(actual).toBe(20);
    });
  });
});

Kapsama raporuyla birlikte birim test sonuçları:

 PASS  src/stackoverflow/59796928/app.test.jsx (11.688s)
  59796928
    #handleSubmit
       should pass (16ms)
    #handleMultiply
       should pass (9ms)

-----------|----------|----------|----------|----------|-------------------|
File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files  |    90.48 |      100 |    85.71 |    94.44 |                   |
 app.jsx   |      100 |      100 |      100 |      100 |                   |
 table.jsx |       50 |      100 |        0 |    66.67 |                 4 |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        13.936s

Kaynak kodu: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59796928


Form bir alt bileşendeyse ne olur? Test formunda handleSubmit'i nasıl tetiklerim, diğeri form gönderirken? Teşekkür ederim
user3808307
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.