/KestrelMock

A .Net HTTP mock server.

Primary LanguageC#MIT LicenseMIT

Kestrel Mock

Build status Nuget version

A .Net Core HTTP mock server.

Example Nuget Reference Usage (RunAsync)

For direct use in a test project you can add the KestralMock nuget package and RunAsync. This will startup the webserver and return so your tests can use the mock API's configured in appsettings.json. See example appsetting.json below. By default, the mock endpoints will use http://localhost:60000.

var config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();

KestrelMock.RunAsync(config);

Example Nuget Reference Usage (CreateWebHostBuilder)

For direct use in a test project you can add the KestralMock nuget package and call CreateWebHostBuilder. CreateWebHostBuilder will return the web host so you can controll the start and stop of the mock server.

webHost = KestrelMock.CreateWebHostBuilder(new string[] { YourUrl }, YourConfigurationRoot).Build();
webHost.Start();

Example Server Usage (Run)

Server will run and not return until the process shuts down. See KestrelMockServer project as an example.

var config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();

KestrelMock.Run(config);

Install

dotnet add package KestrelMock

Example Mocks setup via appsettings.json

{
   "MockSettings":[
      {
         "Request":{
            "Methods":[
               "GET"
            ],
            "PathStartsWith":"/starts/with"
         },
         "Response":{
            "Status":200,
            "Headers":[
               {
                  "Content-Type":"application/json"
               }
            ],
            "Body":"{\"banana_x\": 8000}"
         }
      },
      {
         "Request": {
            "Methods": [ "GET" ],
            "PathMatchesRegex": ".+\\d{4}.+"
         },
         "Response": {
            "Status": 200,
            "Headers": [
               {
                  "Content-Type": "application/json"
               }
            ],
            "Body": "{\"banana_x\": 8000}"
         }
      },
      {
         "Request":{
            "Methods":[
               "POST",
               "GET"
            ],
            "Path":"/hello/world"
         },
         "Response":{
            "Status":200,
            "Headers":[
               {
                  "Content-Type":"application/json"
               }
            ],
            "Body":"{\"hello\": \"world\"}"
         }
      },
      {
         "Request":{
            "Methods":[
               "POST"
            ],
            "Path":"/api/estimate",
            "BodyContains":"00000"
         },
         "Response":{
            "Status":200,
            "Headers":[
               {
                  "Content-Type":"application/json"
               }
            ],
            "Body":"BodyContains Works!"
         }
      },
      {
         "Request":{
            "Methods":[
               "POST"
            ],
            "Path":"/api/estimate",
            "BodyDoesNotContain":"00000"
         },
         "Response":{
            "Status":200,
            "Headers":[
               {
                  "Content-Type":"application/json"
               }
            ],
            "Body":"BodyDoesNotContain works!!"
         }
      },
      {
         "Request":{
            "Methods":[
               "POST",
               "GET"
            ],
            "Path":"/api/fromfile"
         },
         "Response":{
            "Status":200,
            "Headers":[
               {
                  "Content-Type":"application/json"
               }
            ],
            "BodyFromFilePath":"./TestData/body.txt"
         }
      }
   ]
}

Example Mocks setup via admin endpoint

admin endpoint '/kestrelmock/mocks'

GET - returns list of mock settings objects.

POST - body is expected to be HttpMockSetting and adds new mock

DELETE - '/kestrelmock/mocks/YOURID' will delete by HttpMockSetting Id.

Dynamic Mock

Some advanced dynamic mocking capabilities are provided for Json body data responses

Simple body replace

{
   "Request": {
      "Methods": [ "GET" ],
      "PathStartsWith": "/api/persons/carl"
   },
   "Response": {
      "Status": 200,
      "Headers": [
         {
         "Content-Type": "application/json"
         }
      ],
      "Body": "./data/person.json",
      "Replace": {
         "BodyReplacements": {
         "year": "1987",
         "name" : "carl"
         }
      }
   }
}

From Uri : Regex

{
   "Request": {
      "Methods": [ "GET" ],
      "PathStartsWith": "/api/cars"
   },
   "Response": {
      "Status": 200,
      "Headers": [
         {
         "Content-Type": "application/json"
         }
      ],
      "Body": "./my/generic/response.json",
      "Replace": {
          "RegexUriReplacements": {
            "car": "cars/([\\w\\d]+)/.+",
            "color": "/([\\w\\d]+)$"
          }
        }
   }
}

From Uri: Uri template

UriPathReplacements is in the format bodyValue:uriValue

{
      "Request": {
        "Methods": [ "GET" ],
        "PathStartsWith": "/api/wines"
      },
      "Response": {
        "Status": 200,
        "Headers": [
          {
            "Content-Type": "application/json"
          }
        ],
        "Body": "{\"wine\":\"W\",\"color\":\"C\",\"year\":\"Y\"}",
        "Replace": {
          "UriTemplate": "wines/{wine}/{color}?year={year}",
          "BodyReplacements": {
            "year": "1987"
          },
          "UriPathReplacements": {
            "wine": "{wine}",
            "color": "{color}",
            "year":"{year}"
          }
        }
      }
}

DOCKER usage

you can just run kestrel mock default template configuration with

docker run -p 5006:5000 -e ASPNETCORE_URLS=http://*:5000 jasonrowe/kestrelmock

If you want you can create your own image, and then add a custom appsetting.json and responses folder

docker build --no-cache -t kestrelmock:latest -f .\KestrelMockServer\Dockerfile .

docker run -it --rm -p 5000:80 --name myapp kestrelmock:latest

Keep in mind that within the container you can modify the behaviour changing: /app/appsettings.json and /app/responses .
Via docker cp command on a local container you can apply custom settings and mock response files

cd mySettingsFolder

docker cp appsettings.json myapp:/app/appsettings.json

docker cp .\resp\ciao.json myapp:/app/responses/ciao.json

If you prefer build your custom image in CI/CD pipelines, you can append this to the docker file. Else just push to a private image registry, and use that as a starting image

FROM jasonrowe/kestrelmock as KestrelMockServerBase
WORKDIR /app
COPY ["responses","responses"]
COPY ["appsettings.json", "appsettings.json"]
ENTRYPOINT ["dotnet", "KestrelMockServer.dll"]