2017-02-10 6 views
0

Я создал компонент для моего проекта, чтобы помочь с некоторой загрузкой изображения. Компонент работает отлично подходит для меня, однако при попытке модульного тестирования я бегу в некоторые трудности с API HTML Image:Реакция модульного тестирования, тестирование фермента/мокки (или насмешливое?) Html image api

Чтобы начать, мой компонент использует синтаксис new Image(); для загрузки некоторых изображений, здесь является компонентом

import React from 'react'; 

require('./progressive-image.scss'); 

export default class ProgressiveImage extends React.Component { 
    constructor(props) { 
    super(props); 
    } 

    componentDidMount() { 
    const small = this.refs['small-img']; 
    const large = this.refs['large-img']; 

    const img = new Image(); 

    img.src = this.props.smallImg; 
    img.onload = function() { 
     small.classList.add('loaded'); 
    }; 

    const imgLarge = new Image(); 

    imgLarge.src = this.props.largeImg; 
    imgLarge.onload = function() { 
     imgLarge.classList.add('loaded'); 
    }; 

    large.appendChild(imgLarge); 
    } 

    componentDidUpdate() { 
    const small = this.refs['small-img']; 
    const large = this.refs['large-img']; 
    const sameImg = large.childNodes[2].src === this.props.largeImg; 

    // if loading same img, do nothing 
    if (!sameImg) { 
     // remove loaded 
     small.classList.remove('loaded'); 

     const img = new Image(); 

     img.src = this.props.smallImg; 
     img.onload = function() { 
     small.classList.add('loaded'); 
     }; 

     // remove old img 
     large.childNodes[2].remove(); 

     const imgLarge = new Image(); 

     imgLarge.src = this.props.largeImg; 
     imgLarge.onload = function() { 
     imgLarge.classList.add('loaded'); 
     }; 

     large.appendChild(imgLarge); 
    } 
    } 

    render() { 
    const imgStyle = { 'paddingBottom': this.props.heightRatio }; 

    return (
     <div className="progressive-placeholder" ref="large-img"> 
      <img className="img-small" ref="small-img" /> 
      <div style={imgStyle} ></div> 
     </div> 
    ); 
    } 
} 

ProgressiveImage.displayName = 'ProgressiveImage'; 

ProgressiveImage.propTypes = { 
    bgColor: React.PropTypes.string, 
    heightRatio: React.PropTypes.string.isRequired, 
    largeImg: React.PropTypes.string.isRequired, 
    smallImg: React.PropTypes.string.isRequired, 
}; 

Использование ферментов mount полностью рендер, я делаю что-то вроде этого для модульного тестирования componentDidMount (и, надеюсь, componentdidupdate в будущем).

it('should load images on mount',() => { 
    const instance = mount(
      <FollainProgressiveImage 
      bgColor={bgColor} 
      heightRatio={heightRatio} 
      largeImg={largeImg} 
      smallImg={smallImg} 
      /> 
    ); 
    }); 

Однако тест бегун на меня орать, что Image is not defined. Так что я пытался что-то вроде

it('should load images on mount',() => { 
    global.Image = spy(); 
    const instance = mount(
      <FollainProgressiveImage 
      bgColor={bgColor} 
      heightRatio={heightRatio} 
      largeImg={largeImg} 
      smallImg={smallImg} 
      /> 
    ); 
    }); 

Это шпион является sinon.spy, однако это дает мне ошибку First argument to Node.prototype.appendChild must be a Node, но я могу видеть в докладе покрытия, что componentDidMount идет удар.

Я не уверен, как наилучшим образом подойти к тестированию этого, должен ли я полностью издеваться над объектом или есть лучший способ сделать это?

Просто для справки - мой тест окр настроен как:

global.document = jsdom.jsdom('<!doctype html><html><body></body></html>'); 
global.window = document.defaultView; 
global.navigator = {userAgent: 'node.js'}; 

Может быть, это нужно изменить?

Действительно застрял здесь, ища какие-либо входные данные для тестирования этого кода. Благодаря!!

ответ

2

Конструктор Image() является частью браузера, поэтому не в Node.js. Когда вы звоните new Image() в браузер, это эквивалентно вызову new window.Image(). С помощью jsdom вы установили global.window, чтобы эмулировать. Это означает, что теперь у вас есть доступ к window.Image. Если вы хотите сделать его доступным без префикса window, вы можете сделать его глобальным, нет необходимости делать шпион или макет вручную. Просто добавьте это к вашему испытательной установке:

global.Image = window.Image; 
+0

Благодарим вас за разъяснение, это решило проблему, и вы помогли мне понять, почему она не работает! – ajmajmajma

0

После установки и инструкции Mocha для global-jsdom фиксированной этот вопрос для меня.

 Смежные вопросы

  • Нет связанных вопросов^_^