Skip to content
Permalink
Browse files

Full Basic exemple with Consumer/Provider Pact Testing. No Dependency…

… Injection, No TestServer.
  • Loading branch information...
leonardocuco committed Jan 29, 2019
0 parents commit b66f0ed9e9ace28473650ac8ee9ff3a2bce8b309
Showing with 941 additions and 0 deletions.
  1. +15 −0 .gitignore
  2. +18 −0 Consumer/src/ConsumerApp/ConsumerApp.csproj
  3. +16 −0 Consumer/src/ConsumerApp/Models/Vehicul.cs
  4. +22 −0 Consumer/src/ConsumerApp/Program.cs
  5. +49 −0 Consumer/src/ConsumerApp/SimpleConsumerApiClient.cs
  6. +20 −0 Consumer/tests/Consumer.Tests.Pact/Consumer.Tests.Pact.csproj
  7. +60 −0 Consumer/tests/Consumer.Tests.Pact/ConsumerPactClassFixture.cs
  8. +101 −0 Consumer/tests/Consumer.Tests.Pact/SimpleConsumerApiTest.cs
  9. +59 −0 PactNetCore.sln
  10. +38 −0 Provider/scr/ProviderApi/Controllers/VehiculsController.cs
  11. +17 −0 Provider/scr/ProviderApi/Models/Vehicul.cs
  12. +24 −0 Provider/scr/ProviderApi/Program.cs
  13. +30 −0 Provider/scr/ProviderApi/Properties/launchSettings.json
  14. +17 −0 Provider/scr/ProviderApi/ProviderApi.csproj
  15. +13 −0 Provider/scr/ProviderApi/ProviderApi.csproj.user
  16. +14 −0 Provider/scr/ProviderApi/Repositories/IVehiculRepository.cs
  17. +26 −0 Provider/scr/ProviderApi/Repositories/VehiculRepository.cs
  18. +43 −0 Provider/scr/ProviderApi/Startup.cs
  19. +9 −0 Provider/scr/ProviderApi/appsettings.Development.json
  20. +8 −0 Provider/scr/ProviderApi/appsettings.json
  21. +12 −0 Provider/tests/ProviderApi.Tests.Pacts/Middlewares/ProviderState.cs
  22. +73 −0 Provider/tests/ProviderApi.Tests.Pacts/Middlewares/ProviderStateMiddleware.cs
  23. +25 −0 Provider/tests/ProviderApi.Tests.Pacts/ProviderApi.Tests.Pacts.csproj
  24. +35 −0 Provider/tests/ProviderApi.Tests.Pacts/TestStartup.cs
  25. +93 −0 Provider/tests/ProviderApi.Tests.Pacts/Tests/ProviderApiTests.cs
  26. +43 −0 Provider/tests/ProviderApi.Tests.Pacts/XUnitHelpers/XUnitOutput.cs
  27. +61 −0 pacts/consumer-provider.json
@@ -0,0 +1,15 @@
################################################################################
# Ce fichier .gitignore a été automatiquement créé par Microsoft(R) Visual Studio.
################################################################################

/Consumer/src/ConsumerApp/obj
/Consumer/src/ConsumerApp/bin/Debug/netcoreapp2.1
/Consumer/tests/Consumer.Tests.Pact/bin/Debug/netcoreapp2.1/pact-win32/lib
/Consumer/tests/Consumer.Tests.Pact/bin/Debug/netcoreapp2.1/pact-win32/bin
/Consumer/tests/Consumer.Tests.Pact/obj
/Consumer/tests/Consumer.Tests.Pact/bin/Debug/netcoreapp2.1
/Provider/scr/ProviderApi/obj
/Provider/scr/ProviderApi/bin/Debug/netcoreapp2.1
/Provider/tests/ProviderApi.Tests.Pacts/obj
/Provider/tests/ProviderApi.Tests.Pacts/bin/Debug/netcoreapp2.1
/.vs
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
</ItemGroup>

<ItemGroup>
<Reference Include="Newtonsoft.Json">
<HintPath>..\..\..\..\..\..\..\..\Program Files\dotnet\sdk\NuGetFallbackFolder\newtonsoft.json\11.0.2\lib\netstandard2.0\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>

</Project>
@@ -0,0 +1,16 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsumerApp.Models
{
public class Vehicul
{
[JsonProperty("vehiculId")]
public int VehiculId { get; set; }

[JsonProperty("label")]
public string Label { get; set; }
}
}
@@ -0,0 +1,22 @@
using System;
using System.Linq;

namespace ConsumerApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("List of Vehiculs :");
SimpleConsumerApiClient.GetAllVehiculs("http://localhost:53707").GetAwaiter().GetResult()
.ToList()
.ForEach(v => Console.WriteLine(v.Label));

Console.WriteLine();
Console.WriteLine("Best vehicul :");
Console.WriteLine(SimpleConsumerApiClient.GetAllVehiculById(2, "http://localhost:53707").GetAwaiter().GetResult().Label);

Console.ReadKey();
}
}
}
@@ -0,0 +1,49 @@
using ConsumerApp.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace ConsumerApp
{
public static class SimpleConsumerApiClient
{
static public async Task<Vehicul[]> GetAllVehiculs(string baseUri)
{
using (var client = new HttpClient { BaseAddress = new Uri(baseUri) })
{
try
{
var response = await client.GetAsync($"/api/Vehiculs").GetAwaiter().GetResult()
.Content.ReadAsStringAsync();

return JsonConvert.DeserializeObject<Vehicul[]>(response);
}
catch (System.Exception ex)
{
throw new Exception("There was a problem connecting to Provider API.", ex);
}
}
}

static public async Task<Vehicul> GetAllVehiculById(int id, string baseUri)
{
using (var client = new HttpClient { BaseAddress = new Uri(baseUri) })
{
try
{
var response = await client.GetAsync($"/api/Vehiculs/{id}").GetAwaiter().GetResult()
.Content.ReadAsStringAsync();

return JsonConvert.DeserializeObject<Vehicul>(response);
}
catch (System.Exception ex)
{
throw new Exception("There was a problem connecting to Provider API.", ex);
}
}
}
}
}
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="PactNet.Windows" Version="2.4.5" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\ConsumerApp\ConsumerApp.csproj" />
</ItemGroup>

</Project>
@@ -0,0 +1,60 @@
using PactNet;
using PactNet.Mocks.MockHttpService;
using System;
using System.Collections.Generic;
using System.Text;

namespace Consumer.Tests.Pact
{
public class ConsumerPactClassFixture : IDisposable
{
public IPactBuilder PactBuilder { get; private set; }
public IMockProviderService MockProviderService { get; private set; }

public int MockServerPort { get { return 53707; } }
public string MockProviderServiceBaseUri { get { return String.Format("http://localhost:{0}", MockServerPort); } }

public ConsumerPactClassFixture()
{
// Using Spec version 2.0.0 more details at https://goo.gl/UrBSRc
var pactConfig = new PactConfig
{
SpecificationVersion = "2.0.0",
PactDir = @"..\..\..\..\..\..\pacts",
LogDir = @".\pact_logs"
};

PactBuilder = new PactBuilder(pactConfig);

PactBuilder.ServiceConsumer("Consumer")
.HasPactWith("Provider");

MockProviderService = PactBuilder.MockService(MockServerPort);
}

#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls

protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// This will save the pact file once finished.
PactBuilder.Build();
}

disposedValue = true;
}
}

// This code added to correctly implement the disposable pattern.
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
}
#endregion
}
}
@@ -0,0 +1,101 @@
using ConsumerApp;
using ConsumerApp.Models;
using PactNet.Mocks.MockHttpService;
using PactNet.Mocks.MockHttpService.Models;
using System;
using System.Collections.Generic;
using System.Text;
using Xunit;

namespace Consumer.Tests.Pact
{
public class SimpleConsumerApiTest : IClassFixture<ConsumerPactClassFixture>
{
private IMockProviderService _mockProviderService;
private string _mockProviderServiceBaseUri;

public SimpleConsumerApiTest(ConsumerPactClassFixture fixture)
{
_mockProviderService = fixture.MockProviderService;
_mockProviderService.ClearInteractions(); //NOTE: Clears any previously registered interactions before the test is run
_mockProviderServiceBaseUri = fixture.MockProviderServiceBaseUri;
}

[Fact]
public void Return_Valid_Vehicul_Given_A_Specific_Id()
{
#region Arrange
int vehiculId = 2;
_mockProviderService.Given("FullVehiculState")
.UponReceiving("A valid GET request for specific vehicul with valid id parameter")
.With(new ProviderServiceRequest
{
Method = HttpVerb.Get,
Path = $"/api/Vehiculs/{vehiculId}"
})
.WillRespondWith(new ProviderServiceResponse
{
Status = 200,
Headers = new Dictionary<string, object>
{
{ "Content-Type", "application/json; charset=utf-8" }
},
Body = new Vehicul { VehiculId = 2, Label = "Powered Car" }
});

#endregion

#region Act
var result = SimpleConsumerApiClient.GetAllVehiculById(2, _mockProviderServiceBaseUri).GetAwaiter().GetResult();
#endregion

#region Assert
Assert.Equal(2, result.VehiculId);
Assert.Equal("Powered Car", result.Label);
#endregion
}

[Fact]
public void Return_Valid_Vehicul_List()
{
#region Arrange
_mockProviderService.Given("FullVehiculState")
.UponReceiving("A valid GET request for all vehiculs with no parameter")
.With(new ProviderServiceRequest
{
Method = HttpVerb.Get,
Path = $"/api/Vehiculs"
})
.WillRespondWith(new ProviderServiceResponse
{
Status = 200,
Headers = new Dictionary<string, object>
{
{ "Content-Type", "application/json; charset=utf-8" }
},
Body = new Vehicul[]
{
new Vehicul() { VehiculId = 1, Label = "Simple Car" },
new Vehicul() { VehiculId = 2, Label = "Powered Car" },
new Vehicul() { VehiculId = 3, Label = "Three wheel Car" }
}
});

#endregion

#region Act
var result = SimpleConsumerApiClient.GetAllVehiculs(_mockProviderServiceBaseUri).GetAwaiter().GetResult();
#endregion

#region Assert
Assert.Equal(3, result.Length);
Assert.Equal(1, result[0].VehiculId);
Assert.Equal("Simple Car", result[0].Label);
Assert.Equal(2, result[1].VehiculId);
Assert.Equal("Powered Car", result[1].Label);
Assert.Equal(3, result[2].VehiculId);
Assert.Equal("Three wheel Car", result[2].Label);
#endregion
}
}
}
@@ -0,0 +1,59 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.271
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Provider", "Provider", "{A1E80C27-9B59-4F28-B2BD-40E9516BAB05}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scr", "scr", "{A87D75E0-83A2-4E90-B78F-B5A34A8D55A1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProviderApi", "Provider\scr\ProviderApi\ProviderApi.csproj", "{3E741555-12C1-4B88-8F8F-753B76D8DF27}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Consumer", "Consumer", "{A1CDC01E-B136-40DD-819F-25F5D9616930}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{20923C1C-5BA8-4AB1-954C-D625D4079B2F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsumerApp", "Consumer\src\ConsumerApp\ConsumerApp.csproj", "{42E866A3-A81B-47CD-9FAA-F9B7733FDFD2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Consumer.Tests.Pact", "Consumer\tests\Consumer.Tests.Pact\Consumer.Tests.Pact.csproj", "{43CEA3B3-7489-4150-93AA-D4F30DFFE708}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProviderApi.Tests.Pacts", "Provider\tests\ProviderApi.Tests.Pacts\ProviderApi.Tests.Pacts.csproj", "{F2C46957-D2FC-4628-9D9D-D7C106442C18}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3E741555-12C1-4B88-8F8F-753B76D8DF27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3E741555-12C1-4B88-8F8F-753B76D8DF27}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E741555-12C1-4B88-8F8F-753B76D8DF27}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3E741555-12C1-4B88-8F8F-753B76D8DF27}.Release|Any CPU.Build.0 = Release|Any CPU
{42E866A3-A81B-47CD-9FAA-F9B7733FDFD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{42E866A3-A81B-47CD-9FAA-F9B7733FDFD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{42E866A3-A81B-47CD-9FAA-F9B7733FDFD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{42E866A3-A81B-47CD-9FAA-F9B7733FDFD2}.Release|Any CPU.Build.0 = Release|Any CPU
{43CEA3B3-7489-4150-93AA-D4F30DFFE708}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43CEA3B3-7489-4150-93AA-D4F30DFFE708}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43CEA3B3-7489-4150-93AA-D4F30DFFE708}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43CEA3B3-7489-4150-93AA-D4F30DFFE708}.Release|Any CPU.Build.0 = Release|Any CPU
{F2C46957-D2FC-4628-9D9D-D7C106442C18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F2C46957-D2FC-4628-9D9D-D7C106442C18}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F2C46957-D2FC-4628-9D9D-D7C106442C18}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F2C46957-D2FC-4628-9D9D-D7C106442C18}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{A87D75E0-83A2-4E90-B78F-B5A34A8D55A1} = {A1E80C27-9B59-4F28-B2BD-40E9516BAB05}
{3E741555-12C1-4B88-8F8F-753B76D8DF27} = {A87D75E0-83A2-4E90-B78F-B5A34A8D55A1}
{20923C1C-5BA8-4AB1-954C-D625D4079B2F} = {A1CDC01E-B136-40DD-819F-25F5D9616930}
{42E866A3-A81B-47CD-9FAA-F9B7733FDFD2} = {20923C1C-5BA8-4AB1-954C-D625D4079B2F}
{43CEA3B3-7489-4150-93AA-D4F30DFFE708} = {20923C1C-5BA8-4AB1-954C-D625D4079B2F}
{F2C46957-D2FC-4628-9D9D-D7C106442C18} = {A87D75E0-83A2-4E90-B78F-B5A34A8D55A1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C3E8B719-DEF4-4CAF-B521-0C89F4D74431}
EndGlobalSection
EndGlobal

0 comments on commit b66f0ed

Please sign in to comment.
You can’t perform that action at this time.