2017-04-15 3 views
0

Ich teste eine Reaktionskomponente mit Mocha, Chai und Enzym. Die Komponente istReact Testing: Kann die Eigenschaft 'toLowerCase' von undefined nicht lesen

TodoList.js

export class TodoList extends Component { 
    render() { 
     var {todos, searchText, showCompleted, isFetching} = this.props; 
     var renderTodos =() => { 
        if(isFetching){ 
         return (
          <div className='container__message'> 
           <PulseLoader color="#bbb" size="6px" margin="1.5px" /> 
          </div> 
         ); 
        } 
        if(todos.length === 0){ 
         return <p className='container__message'>Nothing to show</p> 
        } 
       return TodoAPI.filterTodos(todos, showCompleted, searchText).map((todo) => { 
        return (
         <Todo key={todo.id} {...todo} /> 
        ) 
       }); 
     } 
     return ( 
      <div> 
       {renderTodos()} 
      </div> 
     ); 
    } 
} 

export default connect(
    (state) => { 
    return state; 
    } 
)(TodoList); 

Diese Komponente verwendet eine andere Funktion, die

TodoAPI.js ist

import $ from 'jquery'; 

module.exports = { 
    filterTodos: function(todos, showCompleted, searchText){ 
     var filteredTodos = todos; 

     filteredTodos = filteredTodos.filter((todo) => { 
      return !todo.completed || showCompleted; // todo is not completed or showCompleted is toggled 
     }); 

     console.log(filteredTodos); 


     filteredTodos = filteredTodos.filter((todo) => { 
      console.log(todo.text); 
      return todo.text.toLowerCase().indexOf(searchText.toLowerCase()) !== -1; 
     }); 

     filteredTodos.sort((a, b) => { 
      if(!a.completed && b.completed){ 
       return -1; 
      } else if(a.completed && !b.completed){ 
       return 1; 
      } else { 
       return 0; 
      } 
     }); 
     return filteredTodos; 
    } 
}; 

Der Test, den ich Tests geschrieben haben, die TodoList.js rendert 2 Todo-Komponenten, wie ich eine Anordnung von zwei Objekten zur Verfügung gestellt habe. TodoList.spec.js

import React from 'react'; 
import ConnectedTodoList, {TodoList} from '../../src/components/TodoList'; 

describe('TodoList', function(){ 
    let todos = [ 
      { 
       id: 1, 
       text: 'some dummy text', 
      }, 
      { 
       id: 2, 
       text: 'some more dummy text', 
      } 
    ]; 
    beforeEach(function(){ 
     this.wrapper = shallow(<TodoList todos={todos} />); 
    }); 

    it('should exist', function(){  
     expect(this.wrapper).to.exist; 
    }); 

    it('should display 2 Todos', function(){ 
     expect(this.wrapper.find('Todo')).to.have.lengthOf(2); 
    }); 
}) 

Aber wenn ich diesen Test ausführen bekomme ich einen Fehler, der ohne Ausführung des Codes

1) TodoList "before each" hook for "should exist": 
    TypeError: Cannot read property 'toLowerCase' of undefined 
    at F:/Study Material/Web/React Projects/ReactTodoApp/src/api/TodoAPI.js:16:43 

Antwort

1

Ihre Fragen ergibt sich aus dieser Linie in TodoList.js: die Übergabe als props zum TodoList Komponente

var {todos, searchText, showCompleted, isFetching} = this.props; 

Dies wird alle diese Werte zu erwarten. Da searchText in den Tests nicht zur Verfügung steht, hat es den Wert undefined, wenn es an filterTodos übergeben wird, wo schließlich searchText.toLowerCase() aufgerufen wird, was den Fehler verursacht.

Ändern der beforeEach Abschnitt Ihrer Tests:

beforeEach(function(){ 
    this.wrapper = shallow(<TodoList todos={todos} searchText='dummy' />); 
}); 

sollte das Problem lösen. Sie sollten wahrscheinlich auch showCompleted und isFetching angeben, damit Sie sich nicht auf Standardwerte verlassen.

+0

Danke Michael für diese detaillierte Antwort. :) –

1

beste Vermutung sagt mir, dass Searchtext nicht definiert ist und so, wenn Sie toLowerCase nennen darauf kann in der TodoAPI die Funktion nicht aufgerufen werden.

Der einzige andere Ort, den Sie anLowerCase gewöhnt haben, ist der Todo-Text selbst, den Sie durch eine Requisite bereitstellen.

Verwandte Themen