2016-12-15 55 views
1

我試圖從Jest Tutorial Page啓動基本的例子,使用玩笑,反應,打字稿開玩笑/反應/打字稿編譯錯誤,在教程的例子

Link.tsx

import * as React from 'react'; 

const STATUS = { 
    NORMAL: 'normal', 
    HOVERED: 'hovered', 
}; 

interface theProps { 
    page:string 
} 

export default class Link extends React.Component<theProps,any> { 

    constructor(props) { 
     super(props); 

     this._onMouseEnter = this._onMouseEnter.bind(this); 
     this._onMouseLeave = this._onMouseLeave.bind(this); 

     this.state = { 
      class: STATUS.NORMAL, 
     }; 
    } 

    _onMouseEnter() { 
     this.setState({class: STATUS.HOVERED}); 
    } 

    _onMouseLeave() { 
     this.setState({class: STATUS.NORMAL}); 
    } 

    render() { 
     return (
      <a 
       className={this.state.class} 
       href={this.props.page || '#'} 
       onMouseEnter={this._onMouseEnter} 
       onMouseLeave={this._onMouseLeave}> 
       {this.props.children} 
      </a> 
     ); 
    } 

} 

test.tsx

import * as React from 'react'; 
import Link from '../app/Link'; 
import * as renderer from 'react-test-renderer'; 

it('Link changes the class when hovered',() => { 
    const component = renderer.create(
     <Link page="http://www.facebook.com">Facebook</Link> 
    ); 
    let tree = component.toJSON(); 
    expect(tree).toMatchSnapshot(); 

    // manually trigger the callback 
    tree.props.onMouseEnter(); 
    // re-renderingf 
    tree = component.toJSON(); 
    expect(tree).toMatchSnapshot(); 

    // manually trigger the callback 
    tree.props.onMouseLeave(); 
    // re-rendering 
    tree = component.toJSON(); 
    expect(tree).toMatchSnapshot(); 
}); 

但即使測試運行良好jest,Webpack和IntelliJ都抱怨行tree.props.onMouseEnter();Unresolved function or method onMouseLeave()

這種有意義的,因爲道具對象具有類型{ [propName: string]: string }

有什麼我可以包括跳過這些警告/錯誤信息?

回答

0

let tree: any = component.toJSON(); 

let tree = Component.toJSON(); 
let props = tree.props as any; 

也許這會是接近足夠多? ...

import * as React from "react"; 
import * as renderer from "react-test-renderer"; 
import * as TestUtil from "react-addons-test-utils"; 

interface HTMLProps extends React.HTMLProps<any> { 
    [key: string]: any; 
} 

interface ITree /* reimplements ReactTestRendererJSON */ { 
    type: string; 
    // I'm not sure about this but ... is it close enought ? 
    props: HTMLProps; 
    children: null | Array<string | ITree>; 
    $$typeof?: any; 
} 

function isTree(x: string | ITree): x is ITree { 
    return x && (typeof x !== "string") 
     && x.type !== "undefined" 
     && typeof x.children !== "undefined" // .. or === ("string" || "array" 
     && typeof x.props !== "undefined"; // === "object" 
} 

function isString(x: any): x is string { 
    return typeof x === "string"; 
} 

describe("react-test-renderer",() => { 

    it("Should/Could be typed?",() => { 

     let All = (props: any) => 
      (<div {...props.divProps}> 
       Hello1 
       <span {...props.spanProps}> 
        Hello2 
        <a {...props.aProps}> 
         Hello3 
        </a> 
       </span> 
      </div>); 

     const X3 = (props?: any) => { 
      return <All {...props}></All>; 
     } 

     const X2 = (props?: any) => { 
      return <X3 {...props} />; 
     }; 

     const X1 = (props?: any) => { 
      return <X2 {...props} />; 
     }; 

     let result = { 
      onDrag: false, 
      onDrop: false, 
      onMouseEnter: false 
     }; 

     let onDrag =() => result.onDrag = true; 
     let onDrop =() => result.onDrop = true; 
     let onMouseEnter =() => result.onMouseEnter = true; 

     let _render /*: ReactTestInstance*/ = renderer.create(X1({ 
      divProps: { 
       onDrag 
      }, 
      spanProps: { 
       onDrop 
      }, 
      aProps: { 
       onMouseEnter 
      } 
     })); 

     // 1st Rendered component its a Div 
     let divTree = _render.toJSON() as ITree; 

     // is Not an Element 
     expect(TestUtil.isDOMComponent(divTree as any)) 
      .toBeFalsy(); 
     // is Not a Component 
     expect(TestUtil.isCompositeComponent(divTree as any)) 
      .toBeFalsy(); 
     // is a Tree 
     expect(isTree(divTree)) 
      .toBeTruthy(); 

     // tree.props = 1st rendered DOMElement props , in this case a <div/> 
     expect(divTree.type).toEqual("div"); 
     // not created 
     expect(divTree.props.accept).toBeUndefined(); 
     // should be there, beacuse of divProps 
     expect(typeof divTree.props.onDrag).toEqual("function"); 

     // TODO: ReactTestRenderer.js => Symbol['for']('react.test.json') 
     // expect(tree.$$typeof).toBe("?"); 

     // trigger ! 
     divTree.props.onDrag(null); 

     // Children ... 
     expect(divTree.children.length).toEqual(2); 

     // String children 
     { 
      let text = divTree.children.filter(isString)[0]; 
      if (!isString(text)) { throw "Never"; } 
      expect(text).toEqual("Hello1"); 
     } 

     // For <Span/> 
     let spanTree = divTree.children.filter(isTree)[0]; 

     if (!isTree(spanTree)) { 
      // make peace with the compiler ... 
      throw "never"; 
     } 

     expect(isTree(spanTree)).toBeTruthy(); 
     expect(spanTree.type).toEqual("span"); 
     // String children 
     { 
      let text = spanTree.children.filter(isString)[0]; 
      if (!isString(text)) { throw "Never"; } 
      expect(text).toEqual("Hello2"); 
     } 

     // trigger, [div][span onDrop] 
     spanTree.props.onDrop(null); 

     // For <A/> 
     let aTree = spanTree.children.filter(isTree)[0]; 
     expect(isTree(aTree)).toBeTruthy(); 
     if (!isTree(aTree)) { 
      // make peace with the compiler 
      // ...Its a ITree 
      throw "never"; 
     } 

     expect(aTree.type).toEqual("a"); 
     aTree.props.onMouseEnter(null); 
     let text = aTree.children.filter(isString)[0]; 
     if (!isString(text)) { throw "Never"; } 
     expect(text).toEqual("Hello3"); 


     expect(result).toEqual(
      { 
       onDrag: true, 
       onDrop: true, 
       onMouseEnter: true 
      } 
     ); 
    }); 
    // ... 
}); 
+0

把'任何'使它的工作。感覺髒,我仍然對'tree.props.onMouseEnter'感到困惑... –

+0

是的,我使用React.HTMLProps 接口 爲tree.props是相當hacky和誤導, 但它的一種我期待找到/發現; 我從練習學到的是 該道具將被填充道具「完成」 打電話時/創建組件/元素 這樣你就可以測試它的存在, 觸發其處理程序, 也樹/樹項會只填充DOM元素或字符串... 和它的孩子的內部元素應該在'treeItem'兒童 上找到,因此可以'查詢?'結果。 – Dan

+0

如果(這樣的功能存在),我們可以在 在僞sqlx中查詢: 「from tree.children select item where item.type =='a'and item.props。HREF == '#HOME」' 要不然 injsLike: 期望( tree.children .ofType () .find(X => x.type === '一' && X。 props.href =='#HOME') ).toBeSomething(); – Dan

1

我不知道爲什麼,甚至適合你。
Link的道具沒有onMouseEnter也沒有onMouseLeave,它的aLink.render返回。

這也許應該是更喜歡:「有什麼我可以包括跳過這些警告/錯誤信息」

const component = renderer.create(
    <Link page="http://www.facebook.com">Facebook</Link> 
) as Link; 

... 

tree._onMouseEnter(); 
... 
tree._onMouseLeave(); 
+0

使用此解決方案,測試不再編譯。使用'link._onMouseEnter();',IntelliJ很高興,但測試仍然無法編譯。我也覺得這很奇怪,它在第一個地方工作... –

+0

你會得到什麼錯誤? –

+0

TypeError:tree._onMouseEnter不是函數 –