http-server-sim 1.1.0.464

There is a newer version of this package available.
See the version list below for details.
dotnet tool install --global http-server-sim --version 1.1.0.464                
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest # if you are setting up this repo
dotnet tool install --local http-server-sim --version 1.1.0.464                
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=http-server-sim&version=1.1.0.464                
nuke :add-package http-server-sim --version 1.1.0.464                

http-server-sim

Build Status

HTTP Server Simulator is a .NET tool that runs a Web API simulating HTTP endpoints, supporting the development and testing of components that use HTTP.

http-server-sim can be used for various types of tests:

  • Manual Tests Using Predefined Rules: In this mode, http-server-sim is run manually loading a predefined rules file that specifies the behavior for responding to requests.

  • Automated Tests Using Predefined Rules: http-server-sim is run by the test framework, loading a predefined rules file that dictates the behavior when responding to requests.

  • Automated Tests Using Dynamic Rules: In this scenario, http-server-sim is controlled dynamically by the test. The test can adjust http-server-sim's behavior by managing the rules in real-time. Additionally, the test can request parameters from http-server-sim and use them to verify the behavior of the target application.

Usage

Installation

Install the latest version from NuGet:

dotnet tool install --global http-server-sim

Once http-server-sim is installed as a global tool, it can run from any folder. For other versions and more information, visit NuGet package http-server-sim and dotnet tool install.

Running http-server-sim

Running http-server-sim using default options:

# Start the simulator
http-server-sim
# Send a GET request to the simulator from another terminal
curl --location 'http://localhost:5000/data' -v

Simulator output

Request:
HTTP/1.1 - GET - http://localhost:5000/data
Headers:
  Accept: */*
  Host: localhost:5000
  User-Agent: curl/8.7.1
Body:
[Not present]
End of Request


Response:
Status Code: 200
Headers:
[Not present]
Body:
[Not present]
End of Response

http-server-sim attempts to match a request to a rule. When a rule is found, it responds with the response defined in that rule. If no matching rule is found, it responds with a configurable default response, which has a Status Code 200 and no content.

Running http-server-sim setting a default response content:

# Start the simulator setting a default content with a json
http-server-sim --DefaultContentType application/json --DefaultContentValue "{""name"":""Juan""}"
# Send a GET request to the simulator from another terminal
curl --location 'http://localhost:5000/data' -v

Simulator output

...
Response:
Status Code: 200
Headers:
  Content-Type: application/json
Body:
{"name":"Juan"}
End of Response

Another example of setting a default response indicating that a resource not was found.

http-server-sim --DefaultContentType text/plain --DefaultContentValue "Resource not found" --DefaultStatusCode 404

Rule file

The simulation of endpoints is based on a rule file. Here’s how it can be set up:

  1. Create a rule file defining conditions and a response message.
  2. Place the rule file in the appropriate directory.
  3. Run the simulator with the rule file.

Example of rule file.

{
  "rules": [
    {
      "name": "customers-post",
      "description": "",
      "conditions": [
        { "field": "Method", "operator": "Equals", "value": "POST" },
        { "field": "Path", "operator": "Contains", "value": "/customers" }
      ],
      "response": {
        "statusCode": 200
      }
    }
  ]
}
# Loading rules from a file in the current directory
http-server-sim --Rules rules.json
# Send a POST request (will be handled by the rule called customers-post):
curl --location 'http://localhost:5000/customers' --header 'Content-Type: application/json' --data '{"id":10,"name":"Juan"}' -v

http-server-sim returns a response with Status Code 200.

Saving request and response messages to files

# Save request and response to the folder messages-history under the current directory
http-server-sim --SaveRequests messages-history --SaveResponses messages-history
  • The directory can be a full path, e.g., C:\temp\http-server-sim-messages, or a relative directory under the current directory, e.g., messages-history.
  • Messages are saved using a GUID as the name, with the .req extension for request messages and the .res extension for response messages.
  • Keep in mind that files are not deleted automatically. If you have a long-running process creating files, the hard drive may eventually run out of space.

http-server-sim CLI options

Option Description
--ControlUrl <url> URL for managing rules dynamically. Not required. Example: http://localhost:5001.
--DefaultContentType <value> The Content-Type used in a response message when no rule matching the request is found.
--DefaultContentValue <value> The Content used in a response message when no rule matching the request is found.
--DefaultStatusCode <value> The HTTP status code used in a response message when no rule matching the request is found. Default: 200.
--Help Prints the help.
--LogControlRequestAndResponse Whether control requests and responses are logged. Default: false.
--LogRequestAndResponse Whether requests and responses are logged. Default: true.
--RequestBodyLogLimit <limit> Maximum request body size to log (in bytes). Default: 4096.
--ResponseBodyLogLimit <limit> Maximum response body size to log (in bytes). Default: 4096.
--Rules <file-name> \| <path> Rules file. It can be a file name of a file that exists in the current directory or a full path to a file.
--SaveRequests <directory> The directory where request messages are saved.
--SaveResponses <directory> The directory where response messages are saved.
--Url <url> URL for simulating endpoints. Default: http://localhost:5000.
--Url and --ControlUrl cannot share the same value.

Configuring application logs

http-server-sim generates logs like any other ASP.NET application. Log levels can be controlled by using an appsettings.json file in the current directory or by passing optional parameters.

Configuration file

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware": "Information",
      "HttpServerSim": "Information"
    }
  }
}

To avoid information logs from Microsoft.AspNetCore like this one

info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished HTTP/1.1 GET http://localhost:5000/customers - 200 - application/json 77.6842ms

add option --Logging:LogLevel:Microsoft.AspNetCore Warning to the command line or use an appsettings.json file setting "Microsoft.AspNetCore": "Warning"

Rule conditions

When http-server-sim processes a request, it uses rule conditions to match a rule to the request.

Example of conditions:

"conditions": [
  { "field": "Method", "operator": "Equals", "value": "POST" },
  { "field": "Path", "operator": "Contains", "value": "/customers" }
]

A rule with these conditions is applied when:

  • The request method is POST, and
  • The URL path contains /customers.

There are two types of conditions, Method and Path

  1. Method Conditions: These specify the HTTP method (e.g., GET, POST) that the request must match.
  2. URL Path Conditions: These specify the URL path that the request must match.

The supported operators are: Equals, StartWith, and Contains

Response messages

When http-server-sim identifies a rule that matches a request, it prepares a response message based on the response section of the rule.

Response properties:

Property Description
statusCode Status code of the response message. Default: 200
headers A collection of headers. Example: "headers": [ { "key": "Server", "value": ["http-server-sim"] } ]
contentType Content type of a response with a content, this value is used to create the header Content-Type. Example: application/json
contentValue Value used in the content, can be a text, a full path to a file, or a file name when the file exists in the current directory. Example: person-1.json
contentValueType Defines whether contentValue is a text or a file. Possible values: Text or File. Default: Text
encoding Defines an encoding to apply to the content. Default: None. Supported values: GZip

Example of a response defining a message with Status Code 400.

"response": {
  "statusCode": 400
  }

Example of a response defining a message with Status Code 200 and headers Server (with a single value) and Header-1 (with multiple values)

"response": {
  "statusCode": 200,
  "headers": [
    { "key": "Server", "value": ["http-server-sim"] },
    { "key": "Header-1", "value": ["val-1", "val-2"] }
  ]
}

Example of a response with a plain text content.

"response": {
  "contentType": "text/plain",
  "contentValue": "Thank you for the notification",
}

Example of a response using a json file that exists in the current directory.

"response": {
  "contentType": "application/json",
  "contentValue": "person-1.json",
  "contentValueType": "File"
}

Example of a response using an in-line json.

"response": {
  "contentType": "application/json",
  "contentValue": "{\"name\":\"Juan\"}"
}

Example of a response using a json file that exists in the current directory and compressing the content with gzip.

"response": {
  "contentType": "application/json",
  "contentValue": "person-1.json",
  "contentValueType": "File",
  "encoding": "GZip"
}

Using http-server-sim for Test Automation

http-server-sim can be used to implement test automation. Its behavior can be controlled dynamically from the test by creating rules on the fly.

In order to host and control http-server-sim you need to used classes defined in NuGet package http-server-sim-client

Examples of using http-server-sim for Test Automation

Hosting http-server-sim in a test

The HttpServerSimHost class can be used to run http-server-sim as a process within the test.

// Constructor
public HttpServerSimHost(string simulatorUrl, string workingDirectory, string filenameOrCommand, string args)
// Initializing and starting http-server-sim
[TestInitialize]
public void Initialize()
{
    testHost = new HttpServerSimHost(simulatorUrl, testDirectory, "http-server-sim", $"--ControlUrl http://localhost:5001 --DefaultStatusCode 404 --Logging:LogLevel:HttpServerSim Debug --Logging:LogLevel:Microsoft.AspNetCore Warning");
    testHost.Start();
}
// Printing logs from http-server-sim
[TestCleanup]
public void Cleanup()
{
    if (testHost is null) return;

    var sb = new StringBuilder();
    while (testHost.LogsQueue.TryDequeue(out var log))
    {
        sb.AppendLine(log);
    }

    TestContext.WriteLine($"[HttpServerSimHost]{Environment.NewLine}{sb}");

    testHost?.Stop();
    testHost?.Dispose();
}

Controlling http-sever-sim's behavior dynamically

The HttpSimClient class can be used to communicate with http-server-sim. When http-server-sim is run with the --ControlUrl option, it listens on a control endpoint that is accessed by HttpSimClient.

// Constructor
public HttpSimClient(string controlUrl)
// Instantiating HttpSimClient and deleting existent rules
var httpSimClient = new HttpSimClient(controlUrl);
httpSimClient.ClearRules();

Rules can be defined using the RuleBuilder class.

Example of creating and adding a rule.

// Define a rule to respond with a specific response message when a request has '/employees' in the path.
var getCustomerRule = RuleBuilder.CreateRule("get-employees")
    .WithCondition(Field.Path, Operator.Contains, "/employees")
    .WithResponse(new HttpSimResponse { StatusCode = 200, ContentType = "application/json", ContentValue = employeesJson })
    .Rule;

// Create a rule dynamically
httpSimClient.AddRule(getCustomerRule);

Example of a rule that uses multiple conditions.

var conditionMethodEqualsGet = new ConfigCondition { Field = Field.Method, Operator = Operator.Equals, Value = "GET" };
var conditionPathContainsEmployees = new ConfigCondition { Field = Field.Path, Operator = Operator.Contains, Value = "/employees" };

var getCustomerRule = RuleBuilder.CreateRule("get-employees")
    // Setting multiple conditions
    .WithConditions([conditionMethodEqualsGet, conditionPathContainsEmployees])
    .WithResponse(new HttpSimResponse { StatusCode = 200, ContentType = "application/json", ContentValue = employeesJson })
    .Rule;

Example of a rule that returns a text/plain content. Demonstrates a second way of setting multiple conditions.

var rule = RuleBuilder.CreateRule("get-employee-info")
    .WithCondition(field: Field.Method, op: Operator.Equals, value: "GET")
    .WithCondition(field: Field.Path, op: Operator.Contains, value: "employees/info/1")
    .WithTextResponse("employee 1 info")
    .Rule;

Example of a rule that returns a message with JSON content and response headers.

var employee = new { Id = 1, Name = "name-1" };
var headers = new KeyValuePair<string, string[]>[]
{
    new("header-1", ["header-11", "header-12"])
};

var rule = RuleBuilder.CreateRule("get-employee")
    .WithCondition(field: Field.Method, op: Operator.Equals, value: "GET")
    .WithJsonResponse(employee, headers)
    .Rule;

Example of a rule that returns JSON content compressed with gzip.

var employee = new { Id = 1, Name = "name-1" };
var headers = new KeyValuePair<string, string[]>[]
{
    new("Content-Encoding", ["gzip"])
};

var rule = RuleBuilder.CreateRule("get-employee-1-compressed")
    .WithCondition(Field.Path, Operator.Contains, "/employees/1")
    .WithJsonResponse(employee, headers, encoding: HttpSimResponseEncoding.GZip)
    .Rule;

Example of a rule that returns content from a file.

var rule = RuleBuilder.CreateRule("get-employee-1-from-file")
    .WithCondition(Field.Path, Operator.Contains, "/employees/1")
    .ReturnResponseFromFile("employee-1.json")
    .Rule;

Example of a rule that returns a Status Code 610 with no content.

var rule = RuleBuilder.CreateRule("get-employees-status-code")
    .WithCondition(field: Field.Method, op: Operator.Equals, value: "GET")
    .ReturnWithStatusCode(610)
    .Rule;

The HttpSimClient class can be used to verify how rules are applied when handling requests.

Example of verifying that the rule named get-employee-info was used twice.

httpSimClient.VerifyThatRuleWasUsed("get-employee-info", 2);

Example of verifying that the last request handled by a specific rule contains the expected JSON content.

var expected = "{\"id\": 1, \"name\": \"name-1\"}";
httpSimClient.VerifyLastRequestBodyAsJson("create-employee", expected);
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last updated
1.2.0.471 60 8/27/2024
1.1.0.464 73 8/14/2024
1.1.0.435 68 8/7/2024
1.1.0.429 66 8/6/2024
1.1.0.421 51 8/3/2024
1.1.0.420-beta 45 8/3/2024
1.1.0.410 42 7/30/2024
1.1.0.402-beta 57 7/25/2024
1.1.0.394 61 7/23/2024
1.1.0.390-beta 53 7/22/2024