NUC-45: Propertly test FirebaseTelemetryPublisher

This commit is contained in:
Denis-Cosmin Nutiu 2020-04-25 17:14:59 +03:00
parent 2d1bfb1905
commit af9e5d4bf9
3 changed files with 90 additions and 63 deletions

View file

@ -0,0 +1,30 @@
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using HttpClient = NucuCar.Common.HttpClient;
namespace NucuCar.UnitTests.NucuCar.Common.Tests
{
public class MockHttpClient : HttpClient
{
public List<HttpRequestMessage> SendAsyncArgCalls;
public List<HttpResponseMessage> SendAsyncResponses;
private int _sendAsyncCallCounter;
public MockHttpClient(string baseAddress) : base(baseAddress)
{
_sendAsyncCallCounter = 0;
SendAsyncArgCalls = new List<HttpRequestMessage>();
SendAsyncResponses = new List<HttpResponseMessage>();
}
public override Task<HttpResponseMessage> SendAsync(HttpRequestMessage requestMessage)
{
SendAsyncArgCalls.Add(requestMessage);
var response = SendAsyncResponses[_sendAsyncCallCounter];
_sendAsyncCallCounter += 1;
return Task.FromResult(response);
}
}
}

View file

@ -2,11 +2,12 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Moq;
using NucuCar.Domain.Telemetry; using NucuCar.Domain.Telemetry;
using NucuCar.Telemetry; using NucuCar.Telemetry;
using NucuCar.UnitTests.NucuCar.Common.Tests;
using Xunit; using Xunit;
using HttpClient = NucuCar.Common.HttpClient; using HttpClient = NucuCar.Common.HttpClient;
@ -77,31 +78,20 @@ namespace NucuCar.UnitTests.NucuCar.Telemetry.Tests
ConnectionString = "ProjectId=test;CollectionName=test" ConnectionString = "ProjectId=test;CollectionName=test"
}; };
var publisher = new MockTelemetryPublisherFirestore(opts); var publisher = new MockTelemetryPublisherFirestore(opts);
var mockHttpClient = new Mock<HttpClient>("http://testing.com"); var mockHttpClient = new MockHttpClient("http://testing.com");
mockHttpClient.Setup(c => c.SendAsync(It.IsAny<HttpRequestMessage>())) mockHttpClient.SendAsyncResponses.Add(new HttpResponseMessage(HttpStatusCode.OK));
.Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); publisher.SetHttpClient(mockHttpClient);
publisher.SetHttpClient(mockHttpClient.Object);
publisher.SetMockData(new Dictionary<string, object> {["testData"] = 1}); publisher.SetMockData(new Dictionary<string, object> {["testData"] = 1});
// Run // Run
await publisher.PublishAsync(CancellationToken.None); await publisher.PublishAsync(CancellationToken.None);
// Assert // Assert
var expectedContent = "{\"fields\":{\"testData\":{\"integerValue\":1}}}"; var request = mockHttpClient.SendAsyncArgCalls[0];
mockHttpClient.Verify( Assert.Equal(HttpMethod.Post, request.Method);
m => m.SendAsync( Assert.Equal(new Uri("http://testing.com"), request.RequestUri);
It.Is<HttpRequestMessage>( Assert.Equal("{\"fields\":{\"testData\":{\"integerValue\":1}}}",
request => request.Method.Equals(HttpMethod.Post)))); request.Content.ReadAsStringAsync().GetAwaiter().GetResult());
mockHttpClient.Verify(
m => m.SendAsync(
It.Is<HttpRequestMessage>(
request => request.RequestUri.Equals(new Uri("http://testing.com")))));
mockHttpClient.Verify(
m => m.SendAsync(
It.Is<HttpRequestMessage>(
request => request.Content.ReadAsStringAsync().GetAwaiter().GetResult()
.Equals(expectedContent))));
} }
[Fact] [Fact]
@ -113,11 +103,10 @@ namespace NucuCar.UnitTests.NucuCar.Telemetry.Tests
ConnectionString = "ProjectId=test;CollectionName=test" ConnectionString = "ProjectId=test;CollectionName=test"
}; };
var publisher = new MockTelemetryPublisherFirestore(opts); var publisher = new MockTelemetryPublisherFirestore(opts);
var mockHttpClient = new Mock<HttpClient>("http://testing.com"); var mockHttpClient = new MockHttpClient("http://testing.com");
mockHttpClient.Setup(c => c.SendAsync(It.IsAny<HttpRequestMessage>())) mockHttpClient.SendAsyncResponses.Add(new HttpResponseMessage(HttpStatusCode.OK));
.Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)));
publisher.SetHttpClient(mockHttpClient.Object); publisher.SetHttpClient(mockHttpClient);
publisher.SetMockData(new Dictionary<string, object> {["testData"] = 1}); publisher.SetMockData(new Dictionary<string, object> {["testData"] = 1});
var cts = new CancellationTokenSource(); var cts = new CancellationTokenSource();
cts.Cancel(); cts.Cancel();
@ -126,7 +115,7 @@ namespace NucuCar.UnitTests.NucuCar.Telemetry.Tests
await publisher.PublishAsync(cts.Token); await publisher.PublishAsync(cts.Token);
// Assert // Assert
mockHttpClient.Verify(m => m.SendAsync(It.IsAny<HttpRequestMessage>()), Times.Never()); Assert.Equal(mockHttpClient.SendAsyncArgCalls.Count, 0);
} }
[Fact] [Fact]
@ -135,27 +124,49 @@ namespace NucuCar.UnitTests.NucuCar.Telemetry.Tests
// Setup // Setup
var opts = new TelemetryPublisherBuilderOptions() var opts = new TelemetryPublisherBuilderOptions()
{ {
ConnectionString = "ProjectId=test;CollectionName=test" ConnectionString =
"ProjectId=test;CollectionName=test;WebApiKey=TAPIKEY;WebApiEmail=t@emai.com;WebApiPassword=tpass"
}; };
var publisher = new MockTelemetryPublisherFirestore(opts); var publisher = new MockTelemetryPublisherFirestore(opts);
var mockHttpClient = new Mock<HttpClient>("http://testing.com"); var mockHttpClient = new MockHttpClient("http://testing.com");
mockHttpClient.SetupSequence(c => c.SendAsync(It.IsAny<HttpRequestMessage>())) mockHttpClient.SendAsyncResponses.Add(new HttpResponseMessage(HttpStatusCode.Forbidden));
.Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.Forbidden))) mockHttpClient.SendAsyncResponses.Add(new HttpResponseMessage(HttpStatusCode.OK)
.Returns(Task.FromResult( {
new HttpResponseMessage(HttpStatusCode.OK) Content = new StringContent("{\"idToken\":\"testauthtoken\"}")
{Content = new StringContent("{\"idToken\":\"testauthtoken\"}")} });
)) mockHttpClient.SendAsyncResponses.Add(new HttpResponseMessage(HttpStatusCode.OK));
.Returns(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)));
publisher.SetHttpClient(mockHttpClient.Object); publisher.SetHttpClient(mockHttpClient);
publisher.SetMockData(new Dictionary<string, object> {["testData"] = 1}); publisher.SetMockData(new Dictionary<string, object> {["testData"] = 1});
// Run // Run
await publisher.PublishAsync(CancellationToken.None); await publisher.PublishAsync(CancellationToken.None);
// Assert // Assert
// Can't verify because moq doesn't support that, damn C#. Assert.Equal(3, mockHttpClient.SendAsyncArgCalls.Count);
// 1st request - auth denied
Assert.Equal(HttpMethod.Post, mockHttpClient.SendAsyncArgCalls[0].Method);
Assert.Equal(new Uri("http://testing.com"), mockHttpClient.SendAsyncArgCalls[0].RequestUri);
Assert.Equal("{\"fields\":{\"testData\":{\"integerValue\":1}}}",
mockHttpClient.SendAsyncArgCalls[0].Content.ReadAsStringAsync().GetAwaiter().GetResult());
// 2st request - authorizing
Assert.Equal(HttpMethod.Post, mockHttpClient.SendAsyncArgCalls[1].Method);
Assert.Equal(new Uri("https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=TAPIKEY"),
mockHttpClient.SendAsyncArgCalls[1].RequestUri);
Assert.Equal("{\"email\":\"t@emai.com\",\"password\":\"tpass\",\"returnSecureToken\":true}",
mockHttpClient.SendAsyncArgCalls[1].Content.ReadAsStringAsync().GetAwaiter().GetResult());
// 3st request with authorization
Assert.Equal(HttpMethod.Post, mockHttpClient.SendAsyncArgCalls[2].Method);
Assert.Equal(new Uri("http://testing.com"), mockHttpClient.SendAsyncArgCalls[2].RequestUri);
Assert.Equal("{\"fields\":{\"testData\":{\"integerValue\":1}}}",
mockHttpClient.SendAsyncArgCalls[2].Content.ReadAsStringAsync().GetAwaiter().GetResult());
Assert.Equal(new AuthenticationHeaderValue("Bearer", "testauthtoken"),
mockHttpClient.SendAsyncArgCalls[2].Headers.Authorization);
} }
} }
} }

View file

@ -3,43 +3,29 @@
&lt;Assembly Path="/home/denis/.nuget/packages/iot.device.bindings/1.0.0/lib/netcoreapp2.1/Iot.Device.Bindings.dll" /&gt; &lt;Assembly Path="/home/denis/.nuget/packages/iot.device.bindings/1.0.0/lib/netcoreapp2.1/Iot.Device.Bindings.dll" /&gt;
&lt;Assembly Path="/home/denis/.nuget/packages/firebaseresttranslator/0.1.1/lib/netcoreapp3.0/FirebaseRestTranslator.dll" /&gt; &lt;Assembly Path="/home/denis/.nuget/packages/firebaseresttranslator/0.1.1/lib/netcoreapp3.0/FirebaseRestTranslator.dll" /&gt;
&lt;/AssemblyExplorer&gt;</s:String> &lt;/AssemblyExplorer&gt;</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=2d4aa020_002D92b4_002D4819_002Da752_002Df0a1e75a5e68/@EntryIndexedValue">&lt;SessionState ContinuousTestingIsOn="False" ContinuousTestingMode="0" FrameworkVersion="{x:Null}" IsLocked="False" Name="Test_PublishAsync_Authorization_OK" PlatformMonoPreference="{x:Null}" PlatformType="{x:Null}" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt; <s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=59acec6f_002Dda48_002D4e34_002Dbf2a_002D5b52d718278a/@EntryIndexedValue">&lt;SessionState ContinuousTestingIsOn="False" ContinuousTestingMode="0" FrameworkVersion="{x:Null}" IsLocked="False" Name="Test_PublishAsync_Authorization_OK" PlatformMonoPreference="{x:Null}" PlatformType="{x:Null}" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
&lt;TestAncestor&gt; &lt;TestAncestor&gt;
&lt;TestId&gt;xUnit::C6F07921-1052-4945-911E-F328A622F229::.NETCoreApp,Version=v3.0::NucuCar.UnitTests.NucuCar.Telemetry.Tests.TelemetryPublisherFirestoreTest.Test_PublishAsync_Authorization_OK&lt;/TestId&gt; &lt;TestId&gt;xUnit::C6F07921-1052-4945-911E-F328A622F229::.NETCoreApp,Version=v3.1::NucuCar.UnitTests.NucuCar.Telemetry.Tests.TelemetryPublisherFirestoreTest.Test_PublishAsync_Authorization_OK&lt;/TestId&gt;
&lt;/TestAncestor&gt; &lt;/TestAncestor&gt;
&lt;/SessionState&gt;</s:String> &lt;/SessionState&gt;</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=8687c1ea_002Dea4c_002D426e_002Da605_002D3d34b0c68f64/@EntryIndexedValue">&lt;SessionState ContinuousTestingIsOn="False" ContinuousTestingMode="0" FrameworkVersion="{x:Null}" IsLocked="False" Name="Session" PlatformMonoPreference="{x:Null}" PlatformType="{x:Null}" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt; <s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=8687c1ea_002Dea4c_002D426e_002Da605_002D3d34b0c68f64/@EntryIndexedValue">&lt;SessionState ContinuousTestingIsOn="False" ContinuousTestingMode="0" FrameworkVersion="{x:Null}" IsLocked="False" Name="Session" PlatformMonoPreference="{x:Null}" PlatformType="{x:Null}" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
&lt;Or&gt; &lt;Or&gt;
&lt;Or&gt; &lt;Or&gt;
&lt;Or&gt;
&lt;Or&gt;
&lt;Or&gt;
&lt;Or&gt;
&lt;TestAncestor&gt;
&lt;TestId&gt;xUnit::C6F07921-1052-4945-911E-F328A622F229::.NETCoreApp,Version=v3.0::NucuCar.UnitTests.NucuCar.Telemetry.Tests.TelemetryPublisherFirestoreTest.Test_PublishAsync_OK&lt;/TestId&gt;
&lt;/TestAncestor&gt;
&lt;TestAncestor&gt;
&lt;TestId&gt;xUnit::C6F07921-1052-4945-911E-F328A622F229::.NETCoreApp,Version=v3.0::NucuCar.UnitTests.NucuCar.Telemetry.Tests.TelemetryPublisherFirestoreTest.Test_PublishAsync_BadProjectId&lt;/TestId&gt;
&lt;/TestAncestor&gt;
&lt;/Or&gt;
&lt;TestAncestor&gt;
&lt;TestId&gt;xUnit::C6F07921-1052-4945-911E-F328A622F229::.NETCoreApp,Version=v3.0::NucuCar.UnitTests.NucuCar.Telemetry.Tests.TelemetryPublisherFirestoreTest.Test_PublishAsync_CollectiontName&lt;/TestId&gt;
&lt;/TestAncestor&gt;
&lt;/Or&gt;
&lt;TestAncestor&gt;
&lt;TestId&gt;xUnit::C6F07921-1052-4945-911E-F328A622F229::.NETCoreApp,Version=v3.0::NucuCar.UnitTests.NucuCar.Telemetry.Tests.TelemetryPublisherFirestoreTest.Test_PublishAsync_Error_Timeout&lt;/TestId&gt;
&lt;/TestAncestor&gt;
&lt;/Or&gt;
&lt;TestAncestor&gt;
&lt;TestId&gt;xUnit::C6F07921-1052-4945-911E-F328A622F229::.NETCoreApp,Version=v3.0::NucuCar.UnitTests.NucuCar.Telemetry.Tests.TelemetryPublisherFirestoreTest.Test_PublishAsync_Cancel&lt;/TestId&gt;
&lt;/TestAncestor&gt;
&lt;/Or&gt;
&lt;TestAncestor&gt; &lt;TestAncestor&gt;
&lt;TestId&gt;xUnit::C6F07921-1052-4945-911E-F328A622F229::.NETCoreApp,Version=v3.0::NucuCar.UnitTests.NucuCar.Telemetry.Tests.TelemetryPublisherFirestoreTest.Test_PublishAsync_UnknownError&lt;/TestId&gt; &lt;TestId&gt;xUnit::C6F07921-1052-4945-911E-F328A622F229::.NETCoreApp,Version=v3.1::NucuCar.UnitTests.NucuCar.Telemetry.Tests.TelemetryPublisherFirestoreTest.Test_PublishAsync_OK&lt;/TestId&gt;
&lt;/TestAncestor&gt;
&lt;TestAncestor&gt;
&lt;TestId&gt;xUnit::C6F07921-1052-4945-911E-F328A622F229::.NETCoreApp,Version=v3.1::NucuCar.UnitTests.NucuCar.Telemetry.Tests.TelemetryPublisherFirestoreTest.Test_PublishAsync_Cancel&lt;/TestId&gt;
&lt;/TestAncestor&gt; &lt;/TestAncestor&gt;
&lt;/Or&gt; &lt;/Or&gt;
&lt;TestAncestor&gt; &lt;TestAncestor&gt;
&lt;TestId&gt;xUnit::C6F07921-1052-4945-911E-F328A622F229::.NETCoreApp,Version=v3.0::NucuCar.UnitTests.NucuCar.Telemetry.Tests.TelemetryPublisherFirestoreTest.Test_PublishAsync_AuthorizationFail&lt;/TestId&gt; &lt;TestId&gt;xUnit::C6F07921-1052-4945-911E-F328A622F229::.NETCoreApp,Version=v3.1::NucuCar.UnitTests.NucuCar.Telemetry.Tests.TelemetryPublisherFirestoreTest.Test_PublishAsync_Authorization_OK&lt;/TestId&gt;
&lt;/TestAncestor&gt; &lt;/TestAncestor&gt;
&lt;/Or&gt; &lt;/Or&gt;
&lt;/SessionState&gt;</s:String>
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=e8af539e_002D0b50_002D476d_002Daa84_002D80fbff5a748b/@EntryIndexedValue">&lt;SessionState ContinuousTestingIsOn="False" ContinuousTestingMode="0" FrameworkVersion="{x:Null}" IsLocked="False" Name="Test_PublishAsync_OK" PlatformMonoPreference="{x:Null}" PlatformType="{x:Null}" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
&lt;TestAncestor&gt;
&lt;TestId&gt;xUnit::C6F07921-1052-4945-911E-F328A622F229::.NETCoreApp,Version=v3.1::NucuCar.UnitTests.NucuCar.Telemetry.Tests.TelemetryPublisherFirestoreTest.Test_PublishAsync_OK&lt;/TestId&gt;
&lt;/TestAncestor&gt;
&lt;/SessionState&gt;</s:String></wpf:ResourceDictionary> &lt;/SessionState&gt;</s:String></wpf:ResourceDictionary>