Skip to content

Commit c0a0894

Browse files
committed
Keep provider compatibility tests in provider suites
Root cause: the shared test bases eagerly created live geocoder instances in their constructors, which pushed cheap constructor checks into separate files and made the test layout drift away from provider-specific suites. Switching the base tests to lazy generic geocoder access keeps those checks colocated without extra wrapper classes or reflection hacks.
1 parent 5aa4c4d commit c0a0894

11 files changed

Lines changed: 158 additions & 256 deletions

test/Geocoding.Tests/AsyncGeocoderTest.cs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,33 @@ namespace Geocoding.Tests;
55

66
public abstract class AsyncGeocoderTest
77
{
8-
private readonly IGeocoder _asyncGeocoder;
8+
private IGeocoder? _asyncGeocoder;
99
protected readonly SettingsFixture _settings;
1010

1111
protected AsyncGeocoderTest(SettingsFixture settings)
1212
{
1313
CultureInfo.CurrentCulture = new CultureInfo("en-us");
1414

1515
_settings = settings;
16-
_asyncGeocoder = CreateAsyncGeocoder();
1716
}
1817

1918
protected abstract IGeocoder CreateAsyncGeocoder();
2019

20+
private IGeocoder GetGeocoder()
21+
{
22+
return _asyncGeocoder ??= CreateAsyncGeocoder();
23+
}
24+
25+
protected TGeocoder GetGeocoder<TGeocoder>() where TGeocoder : class, IGeocoder
26+
{
27+
return GetGeocoder() as TGeocoder ?? throw new InvalidOperationException($"Expected geocoder of type {typeof(TGeocoder).Name}.");
28+
}
29+
2130
[Fact]
2231
public async Task Geocode_ValidAddress_ReturnsExpectedResult()
2332
{
2433
// Act
25-
var addresses = await _asyncGeocoder.GeocodeAsync("1600 pennsylvania ave nw, washington dc", TestContext.Current.CancellationToken);
34+
var addresses = await GetGeocoder().GeocodeAsync("1600 pennsylvania ave nw, washington dc", TestContext.Current.CancellationToken);
2635

2736
// Assert
2837
addresses.First().AssertWhiteHouse();
@@ -32,7 +41,7 @@ public async Task Geocode_ValidAddress_ReturnsExpectedResult()
3241
public async Task Geocode_NormalizedAddress_ReturnsExpectedResult()
3342
{
3443
// Act
35-
var addresses = await _asyncGeocoder.GeocodeAsync("1600 pennsylvania ave nw", "washington", "dc", null!, null!, TestContext.Current.CancellationToken);
44+
var addresses = await GetGeocoder().GeocodeAsync("1600 pennsylvania ave nw", "washington", "dc", null!, null!, TestContext.Current.CancellationToken);
3645

3746
// Assert
3847
addresses.First().AssertWhiteHouse();
@@ -47,7 +56,7 @@ public async Task Geocode_DifferentCulture_ReturnsExpectedResult(string cultureN
4756
CultureInfo.CurrentCulture = new CultureInfo(cultureName);
4857

4958
// Act
50-
var addresses = await _asyncGeocoder.GeocodeAsync("24 sussex drive ottawa, ontario", TestContext.Current.CancellationToken);
59+
var addresses = await GetGeocoder().GeocodeAsync("24 sussex drive ottawa, ontario", TestContext.Current.CancellationToken);
5160

5261
// Assert
5362
addresses.First().AssertCanadianPrimeMinister();
@@ -62,7 +71,7 @@ public async Task ReverseGeocode_DifferentCulture_ReturnsExpectedResult(string c
6271
CultureInfo.CurrentCulture = new CultureInfo(cultureName);
6372

6473
// Act
65-
var addresses = await _asyncGeocoder.ReverseGeocodeAsync(38.8976777, -77.036517, TestContext.Current.CancellationToken);
74+
var addresses = await GetGeocoder().ReverseGeocodeAsync(38.8976777, -77.036517, TestContext.Current.CancellationToken);
6675

6776
// Assert
6877
addresses.First().AssertWhiteHouseArea();
@@ -72,7 +81,7 @@ public async Task ReverseGeocode_DifferentCulture_ReturnsExpectedResult(string c
7281
public async Task Geocode_InvalidAddress_ReturnsEmpty()
7382
{
7483
// Act
75-
var addresses = await _asyncGeocoder.GeocodeAsync("sdlkf;jasl;kjfldksjfasldf", TestContext.Current.CancellationToken);
84+
var addresses = await GetGeocoder().GeocodeAsync("sdlkf;jasl;kjfldksjfasldf", TestContext.Current.CancellationToken);
7685

7786
// Assert
7887
Assert.Empty(addresses);
@@ -82,7 +91,7 @@ public async Task Geocode_InvalidAddress_ReturnsEmpty()
8291
public async Task Geocode_SpecialCharacters_ReturnsResults()
8392
{
8493
// Act
85-
var addresses = await _asyncGeocoder.GeocodeAsync("Fried St & 2nd St, Gretna, LA 70053", TestContext.Current.CancellationToken);
94+
var addresses = await GetGeocoder().GeocodeAsync("Fried St & 2nd St, Gretna, LA 70053", TestContext.Current.CancellationToken);
8695

8796
// Assert
8897
Assert.NotEmpty(addresses);
@@ -92,7 +101,7 @@ public async Task Geocode_SpecialCharacters_ReturnsResults()
92101
public async Task Geocode_UnicodeCharacters_ReturnsResults()
93102
{
94103
// Act
95-
var addresses = await _asyncGeocoder.GeocodeAsync("Étretat, France", TestContext.Current.CancellationToken);
104+
var addresses = await GetGeocoder().GeocodeAsync("Étretat, France", TestContext.Current.CancellationToken);
96105

97106
// Assert
98107
Assert.NotEmpty(addresses);
@@ -102,7 +111,7 @@ public async Task Geocode_UnicodeCharacters_ReturnsResults()
102111
public async Task ReverseGeocode_WhiteHouseCoordinates_ReturnsExpectedResult()
103112
{
104113
// Act
105-
var addresses = await _asyncGeocoder.ReverseGeocodeAsync(38.8976777, -77.036517, TestContext.Current.CancellationToken);
114+
var addresses = await GetGeocoder().ReverseGeocodeAsync(38.8976777, -77.036517, TestContext.Current.CancellationToken);
106115

107116
// Assert
108117
addresses.First().AssertWhiteHouse();

test/Geocoding.Tests/AzureMapsAsyncTest.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,19 @@ protected override IGeocoder CreateAsyncGeocoder()
2323
public async Task Geocode_AddressInput_ReturnsCorrectEntityType(string address, EntityType type)
2424
{
2525
// Arrange
26-
var geocoder = (AzureMapsGeocoder)CreateAsyncGeocoder();
26+
var geocoder = GetGeocoder<AzureMapsGeocoder>();
2727

2828
// Act
2929
var results = (await geocoder.GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
3030

3131
// Assert
3232
Assert.Equal(type, results[0].Type);
3333
}
34+
35+
[Fact]
36+
public void Constructor_EmptyApiKey_ThrowsArgumentException()
37+
{
38+
// Act & Assert
39+
Assert.Throws<ArgumentException>(() => new AzureMapsGeocoder(String.Empty));
40+
}
3441
}

test/Geocoding.Tests/BingMapsAsyncTest.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,13 @@ namespace Geocoding.Tests;
66
[Collection("Settings")]
77
public class BingMapsAsyncTest : AsyncGeocoderTest
88
{
9-
private BingMapsGeocoder _bingMapsGeocoder = null!;
10-
119
public BingMapsAsyncTest(SettingsFixture settings)
1210
: base(settings) { }
1311

1412
protected override IGeocoder CreateAsyncGeocoder()
1513
{
1614
SettingsFixture.SkipIfMissing(_settings.BingMapsKey, nameof(SettingsFixture.BingMapsKey));
17-
_bingMapsGeocoder = new BingMapsGeocoder(_settings.BingMapsKey);
18-
return _bingMapsGeocoder;
15+
return new BingMapsGeocoder(_settings.BingMapsKey);
1916
}
2017

2118
[Theory]
@@ -26,8 +23,10 @@ protected override IGeocoder CreateAsyncGeocoder()
2623
[InlineData("1600 pennsylvania ave washington dc", EntityType.Address)]
2724
public async Task Geocode_AddressInput_ReturnsCorrectEntityType(string address, EntityType type)
2825
{
26+
var geocoder = GetGeocoder<BingMapsGeocoder>();
27+
2928
// Act
30-
var result = await _bingMapsGeocoder.GeocodeAsync(address, TestContext.Current.CancellationToken);
29+
var result = await geocoder.GeocodeAsync(address, TestContext.Current.CancellationToken);
3130
var addresses = result.ToArray();
3231

3332
// Assert

test/Geocoding.Tests/BingMapsTest.cs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,13 @@ namespace Geocoding.Tests;
66
[Collection("Settings")]
77
public class BingMapsTest : GeocoderTest
88
{
9-
private BingMapsGeocoder _bingMapsGeocoder = null!;
10-
119
public BingMapsTest(SettingsFixture settings)
1210
: base(settings) { }
1311

1412
protected override IGeocoder CreateGeocoder()
1513
{
1614
SettingsFixture.SkipIfMissing(_settings.BingMapsKey, nameof(SettingsFixture.BingMapsKey));
17-
_bingMapsGeocoder = new BingMapsGeocoder(_settings.BingMapsKey);
18-
return _bingMapsGeocoder;
15+
return new BingMapsGeocoder(_settings.BingMapsKey);
1916
}
2017

2118
[Theory]
@@ -25,10 +22,11 @@ protected override IGeocoder CreateGeocoder()
2522
public async Task Geocode_WithCulture_ReturnsLocalizedAddress(string address, string culture, string result)
2623
{
2724
// Arrange
28-
_bingMapsGeocoder.Culture = culture;
25+
var geocoder = GetGeocoder<BingMapsGeocoder>();
26+
geocoder.Culture = culture;
2927

3028
// Act
31-
var addresses = (await _bingMapsGeocoder.GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
29+
var addresses = (await geocoder.GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
3230

3331
// Assert
3432
Assert.Equal(result, addresses[0].FormattedAddress);
@@ -41,10 +39,11 @@ public async Task Geocode_WithCulture_ReturnsLocalizedAddress(string address, st
4139
public async Task Geocode_WithUserLocation_ReturnsBiasedResult(string address, double userLatitude, double userLongitude, string country)
4240
{
4341
// Arrange
44-
_bingMapsGeocoder.UserLocation = new Location(userLatitude, userLongitude);
42+
var geocoder = GetGeocoder<BingMapsGeocoder>();
43+
geocoder.UserLocation = new Location(userLatitude, userLongitude);
4544

4645
// Act
47-
var addresses = (await _bingMapsGeocoder.GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
46+
var addresses = (await geocoder.GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
4847

4948
// Assert
5049
Assert.Contains(addresses, x => String.Equals(x.CountryRegion, country, StringComparison.Ordinal));
@@ -57,11 +56,12 @@ public async Task Geocode_WithUserLocation_ReturnsBiasedResult(string address, d
5756
public async Task Geocode_WithUserMapView_ReturnsBiasedResult(string address, double userLatitude1, double userLongitude1, double userLatitude2, double userLongitude2, string country)
5857
{
5958
// Arrange
60-
_bingMapsGeocoder.UserMapView = new Bounds(userLatitude1, userLongitude1, userLatitude2, userLongitude2);
61-
_bingMapsGeocoder.MaxResults = 20;
59+
var geocoder = GetGeocoder<BingMapsGeocoder>();
60+
geocoder.UserMapView = new Bounds(userLatitude1, userLongitude1, userLatitude2, userLongitude2);
61+
geocoder.MaxResults = 20;
6262

6363
// Act
64-
var addresses = (await _bingMapsGeocoder.GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
64+
var addresses = (await geocoder.GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
6565

6666
// Assert
6767
Assert.Contains(addresses, x => String.Equals(x.CountryRegion, country, StringComparison.Ordinal));
@@ -72,10 +72,11 @@ public async Task Geocode_WithUserMapView_ReturnsBiasedResult(string address, do
7272
public async Task Geocode_WithIncludeNeighborhood_ReturnsNeighborhood(string address)
7373
{
7474
// Arrange
75-
_bingMapsGeocoder.IncludeNeighborhood = true;
75+
var geocoder = GetGeocoder<BingMapsGeocoder>();
76+
geocoder.IncludeNeighborhood = true;
7677

7778
// Act
78-
var addresses = (await _bingMapsGeocoder.GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
79+
var addresses = (await geocoder.GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
7980

8081
// Assert
8182
Assert.NotNull(addresses[0].Neighborhood);
@@ -85,10 +86,19 @@ public async Task Geocode_WithIncludeNeighborhood_ReturnsNeighborhood(string add
8586
//https://github.com/chadly/Geocoding.net/issues/8
8687
public async Task ReverseGeocode_WhiteHouseCoordinates_ReturnsResults()
8788
{
89+
var geocoder = GetGeocoder<BingMapsGeocoder>();
90+
8891
// Act
89-
var addresses = (await _bingMapsGeocoder.ReverseGeocodeAsync(38.8976777, -77.036517, TestContext.Current.CancellationToken)).ToArray();
92+
var addresses = (await geocoder.ReverseGeocodeAsync(38.8976777, -77.036517, TestContext.Current.CancellationToken)).ToArray();
9093

9194
// Assert
9295
Assert.NotEmpty(addresses);
9396
}
97+
98+
[Fact]
99+
public void Constructor_EmptyApiKey_ThrowsArgumentException()
100+
{
101+
// Act & Assert
102+
Assert.Throws<ArgumentException>(() => new BingMapsGeocoder(String.Empty));
103+
}
94104
}

test/Geocoding.Tests/GeocoderTest.cs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,28 @@ public abstract class GeocoderTest
3131
new object[] { "miss, MO" }
3232
};
3333

34-
private readonly IGeocoder _geocoder;
34+
private IGeocoder? _geocoder;
3535
protected readonly SettingsFixture _settings;
3636

3737
public GeocoderTest(SettingsFixture settings)
3838
{
3939
//Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-us");
4040

4141
_settings = settings;
42-
_geocoder = CreateGeocoder();
4342
}
4443

4544
protected abstract IGeocoder CreateGeocoder();
4645

46+
private IGeocoder GetGeocoder()
47+
{
48+
return _geocoder ??= CreateGeocoder();
49+
}
50+
51+
protected TGeocoder GetGeocoder<TGeocoder>() where TGeocoder : class, IGeocoder
52+
{
53+
return GetGeocoder() as TGeocoder ?? throw new InvalidOperationException($"Expected geocoder of type {typeof(TGeocoder).Name}.");
54+
}
55+
4756
protected static async Task RunInCultureAsync(string cultureName, Func<Task> action)
4857
{
4958
CultureInfo originalCulture = CultureInfo.CurrentCulture;
@@ -68,7 +77,7 @@ protected static async Task RunInCultureAsync(string cultureName, Func<Task> act
6877
public virtual async Task Geocode_ValidAddress_ReturnsExpectedResult(string address)
6978
{
7079
// Act
71-
var addresses = (await _geocoder.GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
80+
var addresses = (await GetGeocoder().GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
7281

7382
// Assert
7483
addresses[0].AssertWhiteHouse();
@@ -78,7 +87,7 @@ public virtual async Task Geocode_ValidAddress_ReturnsExpectedResult(string addr
7887
public virtual async Task Geocode_NormalizedAddress_ReturnsExpectedResult()
7988
{
8089
// Act
81-
var addresses = (await _geocoder.GeocodeAsync("1600 pennsylvania ave nw", "washington", "dc", null!, null!, TestContext.Current.CancellationToken)).ToArray();
90+
var addresses = (await GetGeocoder().GeocodeAsync("1600 pennsylvania ave nw", "washington", "dc", null!, null!, TestContext.Current.CancellationToken)).ToArray();
8291

8392
// Assert
8493
addresses[0].AssertWhiteHouse();
@@ -94,7 +103,7 @@ public virtual Task Geocode_DifferentCulture_ReturnsExpectedResult(string cultur
94103
Assert.Equal(cultureName, CultureInfo.CurrentCulture.Name);
95104

96105
// Act
97-
var addresses = (await _geocoder.GeocodeAsync("24 sussex drive ottawa, ontario", TestContext.Current.CancellationToken)).ToArray();
106+
var addresses = (await GetGeocoder().GeocodeAsync("24 sussex drive ottawa, ontario", TestContext.Current.CancellationToken)).ToArray();
98107

99108
// Assert
100109
addresses[0].AssertCanadianPrimeMinister();
@@ -111,7 +120,7 @@ public virtual Task ReverseGeocode_DifferentCulture_ReturnsExpectedResult(string
111120
Assert.Equal(cultureName, CultureInfo.CurrentCulture.Name);
112121

113122
// Act
114-
var addresses = (await _geocoder.ReverseGeocodeAsync(38.8976777, -77.036517, TestContext.Current.CancellationToken)).ToArray();
123+
var addresses = (await GetGeocoder().ReverseGeocodeAsync(38.8976777, -77.036517, TestContext.Current.CancellationToken)).ToArray();
115124

116125
// Assert
117126
addresses[0].AssertWhiteHouseArea();
@@ -122,7 +131,7 @@ public virtual Task ReverseGeocode_DifferentCulture_ReturnsExpectedResult(string
122131
public virtual async Task Geocode_InvalidAddress_ReturnsEmpty()
123132
{
124133
// Act
125-
var addresses = (await _geocoder.GeocodeAsync("sdlkf;jasl;kjfldksj,fasldf", TestContext.Current.CancellationToken)).ToArray();
134+
var addresses = (await GetGeocoder().GeocodeAsync("sdlkf;jasl;kjfldksj,fasldf", TestContext.Current.CancellationToken)).ToArray();
126135

127136
// Assert
128137
Assert.Empty(addresses);
@@ -133,7 +142,7 @@ public virtual async Task Geocode_InvalidAddress_ReturnsEmpty()
133142
public virtual async Task Geocode_SpecialCharacters_ReturnsResults(string address)
134143
{
135144
// Act
136-
var addresses = (await _geocoder.GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
145+
var addresses = (await GetGeocoder().GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
137146

138147
// Assert
139148
Assert.NotEmpty(addresses);
@@ -144,7 +153,7 @@ public virtual async Task Geocode_SpecialCharacters_ReturnsResults(string addres
144153
public virtual async Task Geocode_StreetIntersection_ReturnsResults(string address)
145154
{
146155
// Act
147-
var addresses = (await _geocoder.GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
156+
var addresses = (await GetGeocoder().GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
148157

149158
// Assert
150159
Assert.NotEmpty(addresses);
@@ -154,7 +163,7 @@ public virtual async Task Geocode_StreetIntersection_ReturnsResults(string addre
154163
public virtual async Task ReverseGeocode_WhiteHouseCoordinates_ReturnsExpectedArea()
155164
{
156165
// Act
157-
var addresses = (await _geocoder.ReverseGeocodeAsync(38.8976777, -77.036517, TestContext.Current.CancellationToken)).ToArray();
166+
var addresses = (await GetGeocoder().ReverseGeocodeAsync(38.8976777, -77.036517, TestContext.Current.CancellationToken)).ToArray();
158167

159168
// Assert
160169
addresses[0].AssertWhiteHouseArea();
@@ -166,7 +175,7 @@ public virtual async Task ReverseGeocode_WhiteHouseCoordinates_ReturnsExpectedAr
166175
public virtual async Task Geocode_InvalidZipCode_ReturnsResults(string address)
167176
{
168177
// Act
169-
var addresses = (await _geocoder.GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
178+
var addresses = (await GetGeocoder().GeocodeAsync(address, TestContext.Current.CancellationToken)).ToArray();
170179

171180
// Assert
172181
Assert.NotEmpty(addresses);

test/Geocoding.Tests/GoogleAsyncGeocoderTest.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ namespace Geocoding.Tests;
66
[Collection("Settings")]
77
public class GoogleAsyncGeocoderTest : AsyncGeocoderTest
88
{
9-
private GoogleGeocoder _googleGeocoder = null!;
10-
119
public GoogleAsyncGeocoderTest(SettingsFixture settings)
1210
: base(settings) { }
1311

@@ -16,9 +14,7 @@ protected override IGeocoder CreateAsyncGeocoder()
1614
String apiKey = _settings.GoogleApiKey;
1715
SettingsFixture.SkipIfMissing(apiKey, nameof(SettingsFixture.GoogleApiKey));
1816
GoogleTestGuard.EnsureAvailable(apiKey);
19-
_googleGeocoder = new GoogleGeocoder(apiKey);
20-
21-
return _googleGeocoder;
17+
return new GoogleGeocoder(apiKey);
2218
}
2319

2420
[Theory]
@@ -29,8 +25,10 @@ protected override IGeocoder CreateAsyncGeocoder()
2925
[InlineData("1600 pennsylvania ave washington dc", GoogleAddressType.Premise)]
3026
public async Task Geocode_AddressInput_ReturnsCorrectAddressType(string address, GoogleAddressType type)
3127
{
28+
var geocoder = GetGeocoder<GoogleGeocoder>();
29+
3230
// Act
33-
var result = await _googleGeocoder.GeocodeAsync(address, TestContext.Current.CancellationToken);
31+
var result = await geocoder.GeocodeAsync(address, TestContext.Current.CancellationToken);
3432
var addresses = result.ToArray();
3533

3634
// Assert

0 commit comments

Comments
 (0)