2016-09-12 6 views
1

Ich benutze Jest Snapshot Tests für eine meiner Komponente und die generierte Snap-Datei ist riesig (199Kb und 4310 Zeilen). Alle Snapshot-Dateien werden auf die Konsole gedruckt (das sind 3-4 Sek. Rendering), wenn der Snapshot-Test fehlschlägt und es mir das Gefühl gab, dass Sie etwas falsch machen.Jest Schnappschüsse testen

Also meine Frage ist: Bin ich Snapshot-Tests richtig verwenden?

Komponentencode:

import _ = require('lodash'); 
import React = require('react'); 
import {TranslatedMessage} from 'translator'; 

import {UserProfile} from './user-profile'; 
import {ICustomerProfile} from '../customer/customer-profile'; 

interface IUserProfile { 
    firstName: string; 
    lastName: string; 
    id: string; 
    customer: ICustomerProfile; 
    job: string; 
    email: string; 
    contacts: string; 
    phoneNumber: string; 
} 

interface IUserProfileProps { 
    contact: IUserProfile; 
} 

interface IUserProfileState {} 

export class UserProfile extends React.Component<IUserProfileProps, IUserProfileState> { 
    constructor(props: IUserProfileProps) { 
     super(props); 
    } 

    public render(): JSX.Element { 
     return (
      <div className="ext-admin-user-infos-details"> 
       <div className="ext-admin-user-infos-details-content"> 
        <div className="row"> 
         <div className="col-md-12"> 
          <h3>{this.props.contact.firstName } {this.props.contact.lastName}</h3> 
          <p className="ext-subtitle"> 
           <span className="ext-minor">{this.props.contact.id}</span> 
          </p> 
         </div> 
        </div> 
        <div className="row"> 
         <div className="col-md-8"> 
          <div className="ext-admin-user-infos-card"> 
           <h6> 
            <TranslatedMessage messageKey="common.labels.customer" /> 
           </h6> 
           <ul> 
            <li>{this.props.contact.customer.name}</li> 
           </ul> 
          </div> 
          <div className="ext-admin-user-infos-card"> 
           <h6> 
            <TranslatedMessage messageKey="admin.contact.infos.job" /> 
           </h6> 
           <ul> 
            <li>{this.props.contact.job}</li> 
           </ul> 
          </div> 
          <div className="ext-admin-user-infos-card"> 
           <h6> 
            <TranslatedMessage messageKey="admin.contact.infos.email" /> 
           </h6> 
           <ul> 
            <li>{this.props.contact.email}</li> 
           </ul> 
          </div> 
         </div> 
         <div className="col-md-4"> 
          <div className="ext-admin-user-infos-card"> 
           <h6> 
            <TranslatedMessage messageKey="common.labels.followed" /> 
           </h6> 
           <ol> 
            {this.renderContacts(this.props.contact.contacts)} 
           </ol> 
          </div> 
          <div className="ext-admin-user-infos-card"> 
           <h6> 
            <TranslatedMessage messageKey="common.labels.phone" /> 
           </h6> 
           <ul> 
            <li>{this.props.contact.phoneNumber}</li> 
           </ul> 
          </div> 
         </div> 
        </div> 
       </div> 
      </div> 
     ); 
    } 

    protected renderContacts(contacts: IUserProfile[]): JSX.Element[] { 
     let contacts= []; 
     if (sales) { 
      _.map(sales, function(contact: IUserProfile): void { 
       salesContact.push(
        <li> 
         { contact.firstName} 
         { contact.lastName} 
        </li> 
       ); 
      }); 
     } 

     return contacts; 
    } 
} 

Und die Testdatei

jest.mock('TranslatedMessage'); 

import React = require('react'); 
import {render} from 'enzyme'; 

import {user} from '../../../tests/tools'; 

import {UserProfile} from '../../../app/components/user-profile/user-profile'; 

describe('UserProfile',() => { 
    it('should match the snapshot',() => { 
     const tree = render(<UserProfile user={user} />); 

     expect(tree).toMatchSnapshot(); 
    }); 
}); 

Antwort

1

Vertrauen, das Gefühl.

Sie verwenden den Snapshot-Test korrekt, aber Sie haben den Punkt erreicht, an dem Sie große Komponenten in kleinere Komponenten zerlegen müssen. Wenn Sie sie auseinander brechen, können Sie sich über die Child-Komponenten lustig machen, was Ihre Snapshot-Größe (pro Snapshot, nicht aggregiert) verringert und Ihre Diffs einfacher zu sehen und zu korrigieren macht.

Zum Beispiel statt:

export class UserProfile extends Component { 
    public render() { 
    return (
     <div className="ext-admin-user-infos-details"> 
     <div className="ext-admin-user-infos-details-content"> 
      <div className="row"> 
      <div className="col-md-12"> 
       <h3>{this.props.contact.firstName } {this.props.contact.lastName}</h3> 
       <p className="ext-subtitle"> 
       <span className="ext-minor">{this.props.contact.id}</span> 
       </p> 
      </div> 
      </div> 
      // ... 
     </div> 
     </div> 
    ) 
    } 
} 

Sie tun:

export class UserProfile extends Component { 
    public render() { 
    return (
     <div className="ext-admin-user-infos-details"> 
     <div className="ext-admin-user-infos-details-content"> 
      <div className="row"> 
      <div className="col-md-12"> 
       <UserProfileName 
       first={this.props.contact.firstName} 
       last={this.props.contact.firstName} 
       contactId={this.props.contact.id} 
       /> 
      </div> 
      </div> 
      // ... 
     </div> 
     </div> 
    ) 
    } 
} 

export class UserProfileName extends Component { 
    public render() { 
    return (
     <div> 
     <h3>{this.props.contact.first} {this.props.contact.last}</h3> 
     <p className="ext-subtitle"> 
      <span className="ext-minor">{this.props.contact.contactId}</span> 
     </p> 
     </div> 
    ); 
    } 
} 

Beachten Sie, dass ich die Logik für die Darstellung den Namen des Benutzers an eine andere Komponente verschoben haben. Hier ist der aktualisierte Test, das Kind Komponente spöttisch:

jest.mock('TranslatedMessage'); 
jest.mock('UserProfileName'); // Mock this and other children 

import React = require('react'); 
import {render} from 'enzyme'; 

import {user} from '../../../tests/tools'; 

import {UserProfile} from '../../../app/components/user-profile/user-profile'; 

describe('UserProfile',() => { 
    it('should match the snapshot',() => { 
    const tree = render(<UserProfile user={user} />); 

    expect(tree).toMatchSnapshot(); 
    }); 
}); 

Der Snapshot für diese wird viel kleiner, als wenn es ist alles in einem Bauteil. Natürlich würden Sie auch Tests für die Kinder-Komponenten haben:

import React = require('react'); 
import {render} from 'enzyme'; 

import {UserProfileName} from '../../../app/components/user-profile/user-profile-name'; 

describe('UserProfileName',() => { 
    it('should match the snapshot with all props',() => { 
    const tree = render(<UserProfile first="Test" last="Testerson" contactId="test-id" />); 

    expect(tree).toMatchSnapshot(); 
    }); 

    it('should render without a first name',() => { 
    const tree = render(<UserProfile last="Testerson" contactId="test-id" />); 

    expect(tree).toMatchSnapshot(); 
    }); 

    it('should render without a last name',() => { 
    const tree = render(<UserProfile first="Test" contactId="test-id" />); 

    expect(tree).toMatchSnapshot(); 
    }); 
}); 

Beachten Sie, dass ich in diesen Tests zwei weitere Fälle am Ende hinzugefügt. Wenn Sie Komponenten wie folgt zerlegen, ist es viel einfacher zu verstehen und für bestimmte Anwendungsfälle der Kinderkomponenten zu testen!

Ein weiterer Vorteil dieses Ansatzes ist, dass Sie jetzt eine wiederverwendbare Komponente haben, die weiß, wie Sie einen Benutzernamen rendern können! Sie können dies verallgemeinern und es bei Bedarf plumpsen.

+0

Danke Herr :) – sanghin

-1

Wenn Sie enzyme verwenden, sollten Sie eine flache machen werden.

import { shallow } from 'enzyme'; 

const component = shallow(<UserProfile user={user} />); 

expect(component.text()).toMatchSnapshot(); 

Sie können auch react-test-renderer als auch verwenden:

import renderer from 'react-test-renderer'; 

const component = renderer.create(<UserProfile user={user} />); 

const tree = component.toJSON(); 

expect(tree).toMatchSnapshot(); 
+0

Mit Ihrer Lösung wurde der Snapshot nur wie ein Objekt mit dem Modell Benutzerwert enthält: {[email protected]} Aber ich danke Ihnen für die Zeit nehmen um eine Antwort zu machen :) – sanghin