1212import sys
1313import os
1414import unittest
15+ from unittest .mock import MagicMock
16+ from shapely .geometry import Polygon
1517from pathlib import Path
18+ import geopandas as gpd
1619
1720from numpy .testing import assert_almost_equal , assert_equal
1821
@@ -31,6 +34,7 @@ def test_clear_cache(self):
3134 assert cache_dir .is_dir ()
3235 assert len ([c for c in cache_dir .glob ("*.p" ) if "gmaps" not in c .name ]) == 0
3336
37+ @unittest .skip ("Skipped to avoid external API calls" )
3438 def test_force_setup (self ):
3539 """Test the `force_setup()` method."""
3640 with Geocoder () as geo :
@@ -39,6 +43,120 @@ def test_force_setup(self):
3943 assert cache_dir .is_dir ()
4044 assert len ([c for c in cache_dir .glob ("*.p" ) if "gmaps" not in c .name ]) == 17
4145
46+ def test_force_setup_without_external_api_calls (self ):
47+ """Test the `force_setup()` method with mocked components."""
48+ with Geocoder () as geo :
49+
50+ def mock_neso_force_setup ():
51+
52+ gsp_boundaries = gpd .GeoDataFrame (
53+ {
54+ "GSPs" : ["BRED_1" , "DEWP" ],
55+ "GSPGroup" : ["_G" , "_N" ],
56+ "geometry" : [
57+ Polygon (
58+ [
59+ (- 2.1 , 53.3 ),
60+ (- 2.0 , 53.3 ),
61+ (- 2.0 , 53.4 ),
62+ (- 2.1 , 53.4 ),
63+ (- 2.1 , 53.3 ),
64+ ]
65+ ),
66+ Polygon (
67+ [
68+ (- 3.2 , 55.9 ),
69+ (- 3.1 , 55.9 ),
70+ (- 3.1 , 56.0 ),
71+ (- 3.2 , 56.0 ),
72+ (- 3.2 , 55.9 ),
73+ ]
74+ ),
75+ ],
76+ },
77+ crs = "EPSG:4326" ,
78+ )
79+ for version in ["20220314" , "20250109" , "20251204" ]:
80+ geo .cache_manager .write (f"gsp_boundaries_{ version } " , gsp_boundaries )
81+ geo .cache_manager .write ("dno_boundaries" , gpd .GeoDataFrame ({}))
82+
83+ def mock_ons_nrs_force_setup ():
84+ llsoa_boundaries = gpd .GeoDataFrame (
85+ {
86+ "region_id" : [
87+ "E01012082" ,
88+ "E01011214" ,
89+ "E01002050" ,
90+ "W01000323" ,
91+ "S01008087" ,
92+ ],
93+ "geometry" : [
94+ Polygon (
95+ [
96+ (- 1.2 , 54.5 ),
97+ (- 1.19 , 54.5 ),
98+ (- 1.19 , 54.55 ),
99+ (- 1.2 , 54.55 ),
100+ (- 1.2 , 54.5 ),
101+ ]
102+ ),
103+ Polygon (
104+ [
105+ (- 1.71 , 53.66 ),
106+ (- 1.69 , 53.66 ),
107+ (- 1.69 , 53.67 ),
108+ (- 1.71 , 53.67 ),
109+ (- 1.71 , 53.66 ),
110+ ]
111+ ),
112+ Polygon (
113+ [
114+ (- 0.07 , 51.57 ),
115+ (- 0.06 , 51.57 ),
116+ (- 0.06 , 51.58 ),
117+ (- 0.07 , 51.58 ),
118+ (- 0.07 , 51.57 ),
119+ ]
120+ ),
121+ Polygon (
122+ [
123+ (- 3.14 , 53.20 ),
124+ (- 3.12 , 53.20 ),
125+ (- 3.12 , 53.21 ),
126+ (- 3.14 , 53.21 ),
127+ (- 3.14 , 53.20 ),
128+ ]
129+ ),
130+ Polygon (
131+ [
132+ (- 4.23 , 55.91 ),
133+ (- 4.21 , 55.91 ),
134+ (- 4.21 , 55.93 ),
135+ (- 4.23 , 55.93 ),
136+ (- 4.23 , 55.91 ),
137+ ]
138+ ),
139+ ],
140+ },
141+ crs = "EPSG:4326" ,
142+ )
143+ for version in ["2011" , "2021" ]:
144+ geo .cache_manager .write (
145+ f"llsoa_boundaries_{ version } " , llsoa_boundaries
146+ )
147+ geo .ons_nrs ._load_datazone_lookup (version )
148+ geo .ons_nrs ._load_constituency_lookup ()
149+ geo .ons_nrs ._load_lad_lookup ()
150+ geo .ons_nrs ._load_llsoa_lookup ()
151+
152+ geo .neso .force_setup = MagicMock (side_effect = mock_neso_force_setup )
153+ geo .ons_nrs .force_setup = MagicMock (side_effect = mock_ons_nrs_force_setup )
154+
155+ geo .force_setup ()
156+
157+ geo .neso .force_setup .assert_called_once ()
158+ geo .ons_nrs .force_setup .assert_called_once ()
159+
42160 def test_geocode_llsoa (self ):
43161 """
44162 Test the `geocode_llsoa()` function with several test cases.
0 commit comments