代码之家  ›  专栏  ›  技术社区  ›  Jake Stevenson

Jest,酶,反应测试Iframe OnLoad

  •  2
  • Jake Stevenson  · 技术社区  · 7 年前

    我的组件包装了react iframe,看起来非常简单:

    export class FilteredIframe extends React.PureComponent<FilteredIframeProps> {
      onload = (e:Window) => {
        console.log("ONLOAD CALLED");
        if (this.props.filters) {
            e.postMessage(this.props.filters, this.props.url);
        }
      }
      render() {
        return (<Iframe url={this.props.url}
            display="initial"
            position="static"
            onLoad={this.onload}
        />);
      }
    }
    

    test("Posts message once the frame has loaded", async () => {
      const payLoad = { data: "data" };
      const result = mount(<FilteredIframe url="https:///www.bing.com" filters={payLoad}/>);
    })
    

    在开玩笑地运行这个时,我从来没有在控制台中看到“ONLOAD CALLED”消息。有什么特别的事情我需要做的jsdom或酶,使它真正调用onLoad?

    2 回复  |  直到 7 年前
        1
  •  0
  •   Shane O'Moore    7 年前

    强制更新已安装的包装对我有效。

    <iframe onLoad={this.iframeLoaded}></iframe>
    

    像这样测试。。。

    const mountWrapper = mount(<App />);
    let container;
    
    describe('iframe', () => {
        beforeEach(() => {
            container = mountWrapper.find('iframe');
        });
    
        it('calls iframeLoaded() when loaded', () => {
            const spy = jest.spyOn(mountWrapper.instance(), 'iframeLoaded');
            mountWrapper.instance().forceUpdate();
            container.simulate('load');
            expect(spy).toHaveBeenCalledTimes(1);
        });
    });
    
        2
  •  0
  •   Oleg Gordeev    6 年前

    您需要将挂载的iframe附加到文档,mount有附加选项来执行此操作。

        3
  •  -1
  •   Jake Stevenson    7 年前

    test("Posts message once the frame has loaded", async () => {
        const payLoad = { data: "data" };
        const result = mount(<FilteredIframe url="https:///www.bing.com" filters={payLoad} />);
        const iframe = result.find("iframe");
    
        //mock contentWindow so we can examine messages
        let receivedFilters = {};
        const mockIFrameContents = {
            contentWindow : {
                postMessage: function (filters, url) {
                    receivedFilters = filters;
                }
            }
        }
        result.instance().setIframeRef(mockIFrameContents);
    
        //Signal the contents have loaded
        iframe.props().onLoad();
        expect(receivedFilters === payLoad).toBeTruthy();
    });
    

    我还对组件进行了一些修改,以便对iframe本身使用ref,并使用ref的contentWindow而不是事件目标。但真正的答案是模拟iframe contentWindow并直接调用它的onLoad(),而不是试图让它实际加载一些东西。