如何测试google.maps.Geocoder?

时间:2019-10-17 20:03:10

标签: javascript reactjs google-maps testing jestjs

  

嗨!我正在尝试编写“简单”测试来检查React类组件状态的变化。具体来说,我正在测试如果Google成功对我发送的某些字符串(地址)进行地址解析,则lat(纬度)和lng(经度)状态是否会发生变化。这是我要测试(i.e. the lat and lng states being set to results[0].geometry.location.lat())的示例:

getLatLong = (address) => {
    const that = this;
    var geo = new google.maps.Geocoder;

    geo.geocode({'address':address},(results, status) => {
        if (status == google.maps.GeocoderStatus.OK) {
            that.setState(
            {
                center: {
                    lat: results[0].geometry.location.lat(),
                    lng: results[0].geometry.location.lng(),
                },
            });
        }
    });
}

在我的jest套件中,由于从未导入google库,因此在编写测试和监视/模拟google.maps.Geocoder时遇到了问题。它是通过脚本附加的,如下所示:

<script async defer
    src=<%="https://maps.googleapis.com/maps/api/js?key=#{Rails.application.config.google_api_key}&callback=initMap"%>>
</script>
  

就这样确认了,代码在手动测试后可以按预期工作,但是在尝试监视时我在测试套件中收到错误:

let geocoderSpy = jest.spyOn(google.maps, 'Geocoder');
  

我收到这样的错误:

  ● EventMap › getLatLong works as intended by getting coordinates of valid locations › calls the geocoder function

ReferenceError: google is not defined

  34 |         let geocoder;
  35 |         beforeEach(() => {
> 36 |             let geocoderSpy = jest.spyOn(google.maps, 'Geocoder');
     |                                          ^
  37 |             geocoder = jest.createSpy('Geocoder', ['geocode']);
  38 |             geocoderSpy.and.returnValue(geocoder);
  39 |         });

  at Object.google (app/javascript/__tests__/EventPage/EventMap.test.jsx:36:42)

然后,我跟进了这个问题,找到了stackoverflow post和这个答案声称可以通过在package.json文件中添加类似的东西来解决这个问题...

"globals": { "google": { } }

这也无法解决我的问题。 我认为解决方案是以某种方式找出如何导入google,但不太确定该怎么做。...如果有人可以帮助我,将不胜感激。我很想学习如何测试这样的东西。预先,非常感谢。奥斯丁

1 个答案:

答案 0 :(得分:1)

您似乎并不是唯一一个遭受用Jest测试Google地图的恐怖之苦的人。我发现周围有很多项目和对话。但是他们似乎都建议通过执行类似以下操作来模拟Google地图库:

const setupGoogleMock = () => {
  /*** Mock Google Maps JavaScript API ***/
  const google = {
    maps: {
      places: {
        AutocompleteService: () => {},
        PlacesServiceStatus: {
          INVALID_REQUEST: 'INVALID_REQUEST',
          NOT_FOUND: 'NOT_FOUND',
          OK: 'OK',
          OVER_QUERY_LIMIT: 'OVER_QUERY_LIMIT',
          REQUEST_DENIED: 'REQUEST_DENIED',
          UNKNOWN_ERROR: 'UNKNOWN_ERROR',
          ZERO_RESULTS: 'ZERO_RESULTS',
        },
      },
      Geocoder: () => {},
      GeocoderStatus: {
        ERROR: 'ERROR',
        INVALID_REQUEST: 'INVALID_REQUEST',
        OK: 'OK',
        OVER_QUERY_LIMIT: 'OVER_QUERY_LIMIT',
        REQUEST_DENIED: 'REQUEST_DENIED',
        UNKNOWN_ERROR: 'UNKNOWN_ERROR',
        ZERO_RESULTS: 'ZERO_RESULTS',
      },
    },
  };
  global.window.google = google;
};

// in test file.
beforeAll(() => {
  setupGoogleMock();
});

(来源:https://github.com/hibiken/react-places-autocomplete/issues/189#issuecomment-377770674

甚至还有一个npm软件包! https://github.com/hupe1980/jest-google-maps-mock

不过,不确定是否能解决您的问题,因为这只能让您检查是否已正确地从API调用正确的方法,而不是检查来自API的正确响应

但是,我不知道在测试这种功能时是否建议进行真正的API调用。