all tests bddfy

This commit is contained in:
Tom Pallister 2016-08-25 16:18:08 +01:00
parent 6d46829ce2
commit 26ee5e6257
5 changed files with 161 additions and 135 deletions

View File

@ -11,7 +11,7 @@ namespace Ocelot.UnitTests
{
private string _upstreamBaseUrl;
private string _downstreamBaseUrl;
private IHostUrlMapRepository _repository;
private readonly IHostUrlMapRepository _repository;
private Response _response;
private Response<HostUrlMap> _getRouteResponse;

View File

@ -3,14 +3,14 @@ using Ocelot.Library.Infrastructure.UrlFinder;
using Ocelot.Library.Infrastructure.Responses;
using Xunit;
using Shouldly;
using System;
using TestStack.BDDfy;
namespace Ocelot.UnitTests
{
public class UpstreamBaseUrlFinderTests
{
private IUpstreamHostUrlFinder _upstreamBaseUrlFinder;
private IHostUrlMapRepository _hostUrlMapRepository;
private readonly IUpstreamHostUrlFinder _upstreamBaseUrlFinder;
private readonly IHostUrlMapRepository _hostUrlMapRepository;
private string _downstreamBaseUrl;
private Response<string> _result;
public UpstreamBaseUrlFinderTests()
@ -22,18 +22,20 @@ namespace Ocelot.UnitTests
[Fact]
public void can_find_base_url()
{
GivenTheBaseUrlMapExists(new HostUrlMap("api.tom.com", "api.laura.com"));
GivenTheDownstreamBaseUrlIs("api.tom.com");
WhenIFindTheMatchingUpstreamBaseUrl();
ThenTheFollowingIsReturned("api.laura.com");
this.Given(x => x.GivenTheBaseUrlMapExists(new HostUrlMap("api.tom.com", "api.laura.com")))
.And(x => x.GivenTheDownstreamBaseUrlIs("api.tom.com"))
.When(x => x.WhenIFindTheMatchingUpstreamBaseUrl())
.Then(x => x.ThenTheFollowingIsReturned("api.laura.com"))
.BDDfy();
}
[Fact]
public void cant_find_base_url()
{
GivenTheDownstreamBaseUrlIs("api.tom.com");
WhenIFindTheMatchingUpstreamBaseUrl();
ThenAnErrorIsReturned();
this.Given(x => x.GivenTheDownstreamBaseUrlIs("api.tom.com"))
.When(x => x.WhenIFindTheMatchingUpstreamBaseUrl())
.Then(x => x.ThenAnErrorIsReturned())
.BDDfy();
}
private void ThenAnErrorIsReturned()

View File

@ -6,52 +6,58 @@ using Xunit;
namespace Ocelot.UnitTests
{
using TestStack.BDDfy;
public class UpstreamUrlPathTemplateVariableReplacerTests
{
private string _upstreamUrlPath;
private UrlPathMatch _urlPathMatch;
private string _result;
private IUpstreamUrlPathTemplateVariableReplacer _upstreamUrlPathReplacer;
private readonly IUpstreamUrlPathTemplateVariableReplacer _upstreamUrlPathReplacer;
public UpstreamUrlPathTemplateVariableReplacerTests()
{
_upstreamUrlPathReplacer = new UpstreamUrlPathTemplateVariableReplacer();
}
[Fact]
public void can_replace_no_template_variables()
{
GivenThereIsAnUpstreamUrlPath("");
GivenThereIsAUrlPathMatch(new UrlPathMatch(true, new List<TemplateVariableNameAndValue>(), ""));
WhenIReplaceTheTemplateVariables();
ThenTheUpstreamUrlPathIsReturned("");
this.Given(x => x.GivenThereIsAnUpstreamUrlPath(""))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, new List<TemplateVariableNameAndValue>(), "")))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned(""))
.BDDfy();
}
[Fact]
public void can_replace_url_no_slash()
{
GivenThereIsAnUpstreamUrlPath("api");
GivenThereIsAUrlPathMatch(new UrlPathMatch(true, new List<TemplateVariableNameAndValue>(), "api"));
WhenIReplaceTheTemplateVariables();
ThenTheUpstreamUrlPathIsReturned("api");
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("api"))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, new List<TemplateVariableNameAndValue>(), "api")))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned("api"))
.BDDfy();
}
[Fact]
public void can_replace_url_one_slash()
{
GivenThereIsAnUpstreamUrlPath("api/");
GivenThereIsAUrlPathMatch(new UrlPathMatch(true, new List<TemplateVariableNameAndValue>(), "api/"));
WhenIReplaceTheTemplateVariables();
ThenTheUpstreamUrlPathIsReturned("api/");
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("api/"))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, new List<TemplateVariableNameAndValue>(), "api/")))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned("api/"))
.BDDfy();
}
[Fact]
public void can_replace_url_multiple_slash()
{
GivenThereIsAnUpstreamUrlPath("api/product/products/");
GivenThereIsAUrlPathMatch(new UrlPathMatch(true, new List<TemplateVariableNameAndValue>(), "api/product/products/"));
WhenIReplaceTheTemplateVariables();
ThenTheUpstreamUrlPathIsReturned("api/product/products/");
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("api/product/products/"))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, new List<TemplateVariableNameAndValue>(), "api/product/products/")))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned("api/product/products/"))
.BDDfy();
}
[Fact]
@ -62,10 +68,11 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{productId}", "1")
};
GivenThereIsAnUpstreamUrlPath("productservice/products/{productId}/");
GivenThereIsAUrlPathMatch(new UrlPathMatch(true, templateVariables, "api/products/{productId}/"));
WhenIReplaceTheTemplateVariables();
ThenTheUpstreamUrlPathIsReturned("productservice/products/1/");
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("productservice/products/{productId}/"))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, templateVariables, "api/products/{productId}/")))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned("productservice/products/1/"))
.BDDfy();
}
[Fact]
@ -76,10 +83,11 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{productId}", "1")
};
GivenThereIsAnUpstreamUrlPath("productservice/products/{productId}/variants");
GivenThereIsAUrlPathMatch(new UrlPathMatch(true, templateVariables, "api/products/{productId}/"));
WhenIReplaceTheTemplateVariables();
ThenTheUpstreamUrlPathIsReturned("productservice/products/1/variants");
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("productservice/products/{productId}/variants"))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, templateVariables, "api/products/{productId}/")))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned("productservice/products/1/variants"))
.BDDfy();
}
[Fact]
@ -91,10 +99,11 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{variantId}", "12")
};
GivenThereIsAnUpstreamUrlPath("productservice/products/{productId}/variants/{variantId}");
GivenThereIsAUrlPathMatch(new UrlPathMatch(true, templateVariables, "api/products/{productId}/{variantId}"));
WhenIReplaceTheTemplateVariables();
ThenTheUpstreamUrlPathIsReturned("productservice/products/1/variants/12");
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("productservice/products/{productId}/variants/{variantId}"))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, templateVariables, "api/products/{productId}/{variantId}")))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned("productservice/products/1/variants/12"))
.BDDfy();
}
[Fact]
@ -107,10 +116,11 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{categoryId}", "34")
};
GivenThereIsAnUpstreamUrlPath("productservice/category/{categoryId}/products/{productId}/variants/{variantId}");
GivenThereIsAUrlPathMatch(new UrlPathMatch(true, templateVariables, "api/products/{categoryId}/{productId}/{variantId}"));
WhenIReplaceTheTemplateVariables();
ThenTheUpstreamUrlPathIsReturned("productservice/category/34/products/1/variants/12");
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("productservice/category/{categoryId}/products/{productId}/variants/{variantId}"))
.And(x => x.GivenThereIsAUrlPathMatch(new UrlPathMatch(true, templateVariables, "api/products/{categoryId}/{productId}/{variantId}")))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheUpstreamUrlPathIsReturned("productservice/category/34/products/1/variants/12"))
.BDDfy();
}
private void GivenThereIsAnUpstreamUrlPath(string upstreamUrlPath)

View File

@ -6,6 +6,8 @@ using Xunit;
namespace Ocelot.UnitTests
{
using TestStack.BDDfy;
public class UrlPathTemplateMapRepositoryTests
{
private string _upstreamUrlPath;
@ -23,42 +25,47 @@ namespace Ocelot.UnitTests
[Fact]
public void can_add_url_path()
{
GivenIHaveAnUpstreamUrlPath("/api/products/products/{productId}");
GivenIWantToRouteRequestsToMyUpstreamUrlPath("/api/products/{productId}");
WhenIAddTheConfiguration();
ThenTheResponseIsSuccesful();
this.Given(x => x.GivenIHaveAnUpstreamUrlPath("/api/products/products/{productId}"))
.And(x => x.GivenIWantToRouteRequestsToMyUpstreamUrlPath("/api/products/{productId}"))
.When(x => x.WhenIAddTheConfiguration())
.Then(x => x.ThenTheResponseIsSuccesful())
.BDDfy();
}
[Fact]
public void can_get_url_path()
{
GivenIHaveSetUpADownstreamUrlPathAndAnUpstreamUrlPath("/api2", "http://www.someapi.com/api2");
WhenIRetrieveTheUrlPathByDownstreamUrl();
ThenTheUrlPathIsReturned();
this.Given(x => x.GivenIHaveSetUpADownstreamUrlPathAndAnUpstreamUrlPath("/api2", "http://www.someapi.com/api2"))
.When(x => x.WhenIRetrieveTheUrlPathByDownstreamUrl())
.Then(x => x.ThenTheUrlPathIsReturned())
.BDDfy();
}
[Fact]
public void can_get_all_urls()
{
GivenIHaveSetUpADownstreamUrlPathAndAnUpstreamUrlPath("/api2", "http://www.someapi.com/api2");
WhenIRetrieveTheUrls();
ThenTheUrlsAreReturned();
this.Given(x => x.GivenIHaveSetUpADownstreamUrlPathAndAnUpstreamUrlPath("/api2", "http://www.someapi.com/api2"))
.When(x => x.WhenIRetrieveTheUrls())
.Then(x => x.ThenTheUrlsAreReturned())
.BDDfy();
}
[Fact]
public void should_return_error_response_when_url_path_already_used()
{
GivenIHaveSetUpADownstreamUrlPathAndAnUpstreamUrlPath("/api2", "http://www.someapi.com/api2");
WhenITryToUseTheSameDownstreamUrl();
ThenTheDownstreamUrlAlreadyBeenUsed();
this.Given(x => x.GivenIHaveSetUpADownstreamUrlPathAndAnUpstreamUrlPath("/api2", "http://www.someapi.com/api2"))
.When(x => x.WhenITryToUseTheSameDownstreamUrl())
.Then(x => x.ThenTheDownstreamUrlAlreadyBeenUsed())
.BDDfy();
}
[Fact]
public void should_return_error_response_if_key_doesnt_exist()
{
GivenIWantToRouteRequestsToMyUpstreamUrlPath("/api");
WhenIRetrieveTheUrlPathByDownstreamUrl();
ThenTheKeyDoesNotExist();
this.Given(x => x.GivenIWantToRouteRequestsToMyUpstreamUrlPath("/api"))
.When(x => x.WhenIRetrieveTheUrlPathByDownstreamUrl())
.Then(x => x.ThenTheKeyDoesNotExist())
.BDDfy();
}
private void WhenITryToUseTheSameDownstreamUrl()

View File

@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Ocelot.Library.Infrastructure.UrlPathMatcher;
@ -7,9 +6,11 @@ using Xunit;
namespace Ocelot.UnitTests
{
using TestStack.BDDfy;
public class UrlPathToUrlPathTemplateMatcherTests
{
private IUrlPathToUrlPathTemplateMatcher _urlMapper;
private readonly IUrlPathToUrlPathTemplateMatcher _urlMapper;
private string _downstreamPath;
private string _downstreamPathTemplate;
private UrlPathMatch _result;
@ -21,56 +22,61 @@ namespace Ocelot.UnitTests
[Fact]
public void can_match_down_stream_url()
{
GivenIHaveADownstreamPath("");
GivenIHaveAnDownstreamPathTemplate("");
WhenIMatchThePaths();
ThenTheResultIsTrue();
ThenTheTemplatesDictionaryIs(new List<TemplateVariableNameAndValue>());
ThenTheUrlPathTemplateIs("");
this.Given(x => x.GivenIHaveADownstreamPath(""))
.And(x => x.GivenIHaveAnDownstreamPathTemplate(""))
.When(x => x.WhenIMatchThePaths())
.And(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(new List<TemplateVariableNameAndValue>()))
.And(x => x.ThenTheUrlPathTemplateIs(""))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_no_slash()
{
GivenIHaveADownstreamPath("api");
GivenIHaveAnDownstreamPathTemplate("api");
WhenIMatchThePaths();
ThenTheResultIsTrue();
ThenTheTemplatesDictionaryIs(new List<TemplateVariableNameAndValue>());
ThenTheUrlPathTemplateIs("api");
this.Given(x => x.GivenIHaveADownstreamPath("api"))
.Given(x => x.GivenIHaveAnDownstreamPathTemplate("api"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(new List<TemplateVariableNameAndValue>()))
.And(x => x.ThenTheUrlPathTemplateIs("api"))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_one_slash()
{
GivenIHaveADownstreamPath("api/");
GivenIHaveAnDownstreamPathTemplate("api/");
WhenIMatchThePaths();
ThenTheResultIsTrue();
ThenTheTemplatesDictionaryIs(new List<TemplateVariableNameAndValue>());
ThenTheUrlPathTemplateIs("api/");
this.Given(x => x.GivenIHaveADownstreamPath("api/"))
.Given(x => x.GivenIHaveAnDownstreamPathTemplate("api/"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(new List<TemplateVariableNameAndValue>()))
.And(x => x.ThenTheUrlPathTemplateIs("api/"))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_downstream_template()
{
GivenIHaveADownstreamPath("api/product/products/");
GivenIHaveAnDownstreamPathTemplate("api/product/products/");
WhenIMatchThePaths();
ThenTheResultIsTrue();
ThenTheTemplatesDictionaryIs(new List<TemplateVariableNameAndValue>());
ThenTheUrlPathTemplateIs("api/product/products/");
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/"))
.Given(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(new List<TemplateVariableNameAndValue>()))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/"))
.BDDfy();
}
[Fact]
public void can_match_down_stream_url_with_downstream_template_with_one_query_string_parameter()
{
GivenIHaveADownstreamPath("api/product/products/?soldout=false");
GivenIHaveAnDownstreamPathTemplate("api/product/products/");
WhenIMatchThePaths();
ThenTheResultIsTrue();
ThenTheTemplatesDictionaryIs(new List<TemplateVariableNameAndValue>());
ThenTheUrlPathTemplateIs("api/product/products/");
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/?soldout=false"))
.Given(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(new List<TemplateVariableNameAndValue>()))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/"))
.BDDfy();
}
[Fact]
@ -81,12 +87,13 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{productId}", "1")
};
GivenIHaveADownstreamPath("api/product/products/1/variants/?soldout=false");
GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}/variants/");
WhenIMatchThePaths();
ThenTheResultIsTrue();
ThenTheTemplatesDictionaryIs(expectedTemplates);
ThenTheUrlPathTemplateIs("api/product/products/{productId}/variants/");
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/variants/?soldout=false"))
.Given(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}/variants/"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(expectedTemplates))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/{productId}/variants/"))
.BDDfy();
}
[Fact]
@ -97,13 +104,13 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{productId}", "1")
};
GivenIHaveADownstreamPath("api/product/products/1");
GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}");
WhenIMatchThePaths();
ThenTheResultIsTrue();
ThenTheTemplatesDictionaryIs(expectedTemplates);
ThenTheUrlPathTemplateIs("api/product/products/{productId}");
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1"))
.Given(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(expectedTemplates))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/{productId}"))
.BDDfy();
}
[Fact]
@ -115,13 +122,13 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{categoryId}", "2")
};
GivenIHaveADownstreamPath("api/product/products/1/2");
GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}/{categoryId}");
WhenIMatchThePaths();
ThenTheResultIsTrue();
ThenTheTemplatesDictionaryIs(expectedTemplates);
ThenTheUrlPathTemplateIs("api/product/products/{productId}/{categoryId}");
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/2"))
.Given(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}/{categoryId}"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(expectedTemplates))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/{productId}/{categoryId}"))
.BDDfy();
}
[Fact]
@ -133,13 +140,13 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{categoryId}", "2")
};
GivenIHaveADownstreamPath("api/product/products/1/categories/2");
GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}/categories/{categoryId}");
WhenIMatchThePaths();
ThenTheResultIsTrue();
ThenTheTemplatesDictionaryIs(expectedTemplates);
ThenTheUrlPathTemplateIs("api/product/products/{productId}/categories/{categoryId}");
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/categories/2"))
.And(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}/categories/{categoryId}"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(expectedTemplates))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/{productId}/categories/{categoryId}"))
.BDDfy();
}
[Fact]
@ -152,13 +159,13 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{variantId}", "123")
};
GivenIHaveADownstreamPath("api/product/products/1/categories/2/variant/123");
GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}/categories/{categoryId}/variant/{variantId}");
WhenIMatchThePaths();
ThenTheResultIsTrue();
ThenTheTemplatesDictionaryIs(expectedTemplates);
ThenTheUrlPathTemplateIs("api/product/products/{productId}/categories/{categoryId}/variant/{variantId}");
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/categories/2/variant/123"))
.And(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}/categories/{categoryId}/variant/{variantId}"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(expectedTemplates))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/{productId}/categories/{categoryId}/variant/{variantId}"))
.BDDfy();
}
[Fact]
@ -170,13 +177,13 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{categoryId}", "2")
};
GivenIHaveADownstreamPath("api/product/products/1/categories/2/variant/");
GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}/categories/{categoryId}/variant/");
WhenIMatchThePaths();
ThenTheResultIsTrue();
ThenTheTemplatesDictionaryIs(expectedTemplates);
ThenTheUrlPathTemplateIs("api/product/products/{productId}/categories/{categoryId}/variant/");
this.Given(x => x.GivenIHaveADownstreamPath("api/product/products/1/categories/2/variant/"))
.And(x => x.GivenIHaveAnDownstreamPathTemplate("api/product/products/{productId}/categories/{categoryId}/variant/"))
.When(x => x.WhenIMatchThePaths())
.Then(x => x.ThenTheResultIsTrue())
.And(x => x.ThenTheTemplatesDictionaryIs(expectedTemplates))
.And(x => x.ThenTheUrlPathTemplateIs("api/product/products/{productId}/categories/{categoryId}/variant/"))
.BDDfy();
}
private void ThenTheTemplatesDictionaryIs(List<TemplateVariableNameAndValue> expectedResults)