2016-07-11 2 views
1

Я пытаюсь написать тест для реагирующего компонента, который отправляет запрос GET Fetch после установки. Тест просто должен проверить, был ли компонент рендерингом, и когда выполняется выборка, я получаю следующее: ReferenceError: fetch is not defined. Я искал вокруг и не мог найти что-нибудь, что исправит мою проблему. Я использую jest и Test Utils для тестирования компонентов.Обратный вызов обхода в компоненте React

Мой код компонента:

export class Home extends Component { 
    constructor(props) { 
     ... 
    } 
    componentDidMount() { 
     fetch('/some/path', { 
      headers: { 
       'Key1': 'Data1', 
       'Key2': Data2 
      } 
     }).then(response => { 
      if (response.status == 200) { 
       response.json().then((data) => { 
        this.context.store.dispatch(setAssets(data)) 
       } 
       ); 
      } else { 
       return (
        <Snackbar 
         open={true} 
         message={"ERROR: " + str(response.status)} 
         autoHideDuration={5000} 
        /> 
       ); 
      } 
     }).catch(e => {}); 
      ... 
     ); 
    } 
    componentWillUnmount() { 
     ... 
    } 
    logout(e) { 
     ... 
    } 
    render() { 
     return (
      <div> 
       <AppBar 
        title="Title" 
        iconElementLeft={ 
         <IconButton> 
          <NavigationClose /> 
         </IconButton> 
        } 
        iconElementRight={ 
         <IconMenu 
          iconButtonElement={ 
           <IconButton> 
            <MoreVertIcon /> 
           </IconButton> 
          } 
          targetOrigin={{ 
           horizontal: 'right', 
           vertical: 'top' 
          }} 
          anchorOrigin={{ 
           horizontal: 'right', 
           vertical: 'top' 
          }} 
         > 
          <MenuItem> 
           Help 
          </MenuItem> 
         </IconMenu> 
        } 
       /> 
       { 
        this.context.store.getState().assets.map((asset, i) => { 
         return (
          <Card 
           title={asset.title} 
           key={i+1} 
          /> 
         ); 
        }) 
       } 
      </div> 
     ); 
    } 
} 

Home.contextTypes = { 
    store: React.PropTypes.object 
} 

export default Home; 

Мой Тест Код:

var home 

describe('Home',() => { 
    beforeEach(() => { 
     let store = createStore(assets); 
     let a = store.dispatch({ 
         type: Asset, 
         assets: [{ 
            'id': 1, 
            'title': 'TITLE' 
           }], 
         }); 
     store.getState().assets = a.assets 

     home = TestUtils.renderIntoDocument(
      <MuiThemeProvider muiTheme={getMuiTheme()}> 
       <Provider store={store}> 
        <Home /> 
       </Provider> 
      </MuiThemeProvider> 
     ); 
    }); 
    it('renders the main page, including cards and appbar',() => {} 

Она ошибки при попытке визуализации Home в документе.

Я пробовал fetch-mock, но это разрешает только ложные вызовы для тестирования API, которые я не пытаюсь сделать, и не издевается над вызовами извлечения в моем компоненте.

Mocking Home не работает, потому что его компонент, который я пытаюсь проверить. Если есть способ издеваться над функцией componentDidMount(), которую я пропустил.

Мне просто нужно обходное решение для вызова извлечения. Есть идеи??

EDIT: Я использую РЕАКТ JSX для компонента и JS для теста

ответ

0

Я нашел ответ, который сработал для меня, и это было очень просто без каких-либо других зависимостей. Это было просто, как хранить основную функцию в переменную и перезаписывать ее, а затем восстановление нормальной работы после TestCase

РЕШЕНИЕ:

var home 

describe('Home',() => { 
    const fetch = global.fetch 

    beforeEach(() => { 
     let store = createStore(assets); 
     let a = store.dispatch({ 
         type: Asset, 
         assets: [{ 
            'id': 1, 
            'title': 'TITLE' 
           }], 
         }); 
     store.getState().assets = a.assets 

     global.fetch =() => {return Promise.resolve('', 200)} 

     home = TestUtils.renderIntoDocument(
      <MuiThemeProvider muiTheme={getMuiTheme()}> 
       <Provider store={store}> 
        <Home /> 
       </Provider> 
      </MuiThemeProvider> 
     ); 
    }); 
    it('renders the main page, including cards and appbar',() => { 
     ... 
    }); 
    afterEach(() => { 
     global.fetch = fetch; 
    }); 
}); 
0

Попробуйте https://github.com/jhnns/rewire:

rewire adds a special setter and getter to modules so you can modify their behaviour for better unit testing

var fetchMock = { ... } 

var rewire = require("rewire"); 
var myComponent = rewire("./myComponent.js"); 
myComponent.__set__("fetch", fetchMock); 
+0

К сожалению, я использую Бабель, который указан в качестве ограничения для ReWire, но я попробовал это в любом случае. ** EDIT: ** Комментарии слишком малы для моего кода, размещены детали как ответ – FRZ

0

К сожалению, я использую столпотворение, который указан в качестве a limitation for rewire, но я попробовал это в любом случае ...

I Добавлено:

... 
store.getState().assets = a.assets 

var fetchMock = function() {return '', 200} 
var rewire = require("rewire"); 
var HomeComponent = rewire('../Home.jsx'); 
HomeComponent.__set__("fetch", fetchMock); 

home = TestUtils.renderIntoDocument(
    <MuiThemeProvider muiTheme={getMuiTheme()}> 
     <Provider store={store}> 
      <Home /> 
     ... 

И получил ошибку:

Error: Cannot find module '../Home.jsx' 
    at Function.Module._resolveFilename (module.js:440:15) 
    at internalRewire (node_modules/rewire/lib/rewire.js:23:25) 
    at rewire (node_modules/rewire/lib/index.js:11:12) 
    at Object.eval (Some/Path/Home-test.js:47:21) 

Я предполагаю, что это потому, что столпотворение:

rename[s] variables in order to emulate certain language features. Rewire will not work in these cases

(Вытащил из Шарди ссылка дала мне)

Однако путь не является переменной, поэтому я задаюсь вопросом, действительно ли babel переименовывает его, и путь на 100% правильный для местоположения моего компонента. Я не думаю, что это потому, что я использую JSX, потому что просто не могу найти компонент, это не проблема совместимости ... Rewire все еще может не работать, даже если он находит файл, хотя, к сожалению, но я бы хотел дать это выстрел все равно.

0

Использование глобального контекста для хранения компонентов могут быть хрупкими и вероятно, не является хорошей идеей для любого значимого проекта.

Вместо этого вы можете использовать шаблон внедрения зависимостей (DI), который является более формализованным методом для переключения различных зависимостей компонентов (в данном случае, выборки) на основе вашей конфигурации времени выполнения. https://en.wikipedia.org/wiki/Dependency_injection

Один аккуратный способ использовать DI является использование инверсии управления (IoC) контейнера, например: https://github.com/jaredhanson/electrolyte

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

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