0

目标:调用一个调用 fetch 调用的函数,以验证它是否适用于我的后端 rest-api(基本上是端到端测试)。

项目:构建的节点模块可以导入到几个反应 Web 应用程序中。该模块仅包含 fetch 调用和最少的逻辑。它基本上是 URL 和设置的美化包装。旨在减少实现应用程序中使用的通用端点所需的工作。

设置:我有一个 docker compose 构建一个 docker 测试容器并拉入我的 rest-api docker 映像(构建在不同的系统中)。测试容器拉入打包的模块并使用依赖项安装它。然后它会在后端+后端所需的其他图像(数据库、登录系统等)旁边显示测试。

问题:如何实现测试来处理调用。

目前我已经尝试直接调用 fetch 方法。这适用于我的登录获取,但任何其他调用都无法发送 cookie。据我了解,我拥有的代码取决于 cookie 的浏览器。我已经尝试了几种解决方案来获取所说的 cookie,但我无法获取 node-fetch 以正确发送它。我最好的猜测是每个测试都在创建一个新的 cookie,但我缺乏完全调试此解决方案路径的知识。

我的发送解决方案路径是尝试使用 puppeteer 加载假页面,然后在页面中评估函数,例如: https ://github.com/puppeteer/puppeteer/issues/2579 如何在 page.evaluate 中使用导入的函数在 Puppeteer with Jest 中?

问题是测试一直无法加载所需的库或其他问题。

代码:

这是我试图测试的大部分电话。我提供的每个函数都围绕它提供 {url:"api/endpoint/path", method:"GET"}。有一些传递给更大的数据帖子。

 export function request(options) {

    //Build options
    options = {
        headers: {
            'Content-Type': 'application/json'
        },
        ...options
    };

    return fetch(options.url, options)
        .then(response => {
            //...

            //Handle errors
            if (!response.ok) {
                return Promise.reject(`${response.status} - ${response.statusText}`);
            }

            try {
                return response.json();
            } catch (e) {
                if (e.name === 'SyntaxError') {
                    return Promise.reject(response.text());
                }
            }
        });
}

我尝试过的测试示例:

import puppeteer from "puppeteer";
import {myCall} from "my-rest-bridge";

it('Check response', async () => {

    //Load browser
    const browser = await puppeteer.launch({
        headless: true,
        args: ['--no-sandbox']
    });
    const page = await browser.newPage();

    //Load page
    await page.goto('http://docker:8888/index.html');

    //Do login
    expect(await page.evaluate(() => login('user', 'password')).toBe(expectedUserResponseJson);

    //Make call
    expect(await page.evaluate(() => myCall(input1, input2)).toBe(expectedCallResponseJson);

    //Close page
    await page.close();
})

4

1 回答 1

0

花了我一段时间,但我为自己的问题建立了一个解决方案。它并不完美,所以如果有人有更好的想法,请回答。

所以我的解决方案如下。我构建了一个附加 git 项目来在 docker 映像中创建一个 shell reactjs 应用程序。这个应用程序拉入我的节点模块,遍历所有导出,然后为每个函数生成一个组件。

import React from 'react';
import * as magicNodeModule from "magic-node-module"; //obviously not the real name
import CallRest from "./CallRest";

/** Core component for the application */
export default class App extends React.Component {

    /** Renders the core application */
    render() {
        const restCalls = Object.keys(magicNodeModule);
        return (
            <div id={"App"}>
                <div>
                    Functions found:
                    <ul id={"function-list"}>
                        {restCalls.map(restCall => <li>{restCall}</li>)}
                    </ul>
                    <hr/>
                </div>
                {
                    restCalls.map(restCall => {
                        return (
                            <CallRest restName={restCall} restCall={magicNodeModule[restCall]}/>
                        );
                    })
                }
            </div>
        )
    }
}


该组件(CallRest)包含一个输入框、提交按钮和输出 div。用户,或者在我的用例 puppeteer 中,可以将数据输入到输入中。然后通过单击提交,它将运行 fetch 调用并将结果输出插入到 div 中。对于那些熟悉该系统的人来说,它的工作原理非常类似于 swagger 2。

该解决方案仍然构建为 compose 中的一系列 docker 图像。虽然它确实需要设置一个反向代理来允许 React 应用程序与后端 API 通信。它还将节点模块的新副本作为压缩包拉入,并将其安装到 docker 中。这样我只需要在蓝月亮中构建一次 shell react docker。

于 2019-12-24T13:32:10.853 回答