http-server-sim-client
1.3.0.523-beta
dotnet add package http-server-sim-client --version 1.3.0.523-beta
NuGet\Install-Package http-server-sim-client -Version 1.3.0.523-beta
<PackageReference Include="http-server-sim-client" Version="1.3.0.523-beta" />
paket add http-server-sim-client --version 1.3.0.523-beta
#r "nuget: http-server-sim-client, 1.3.0.523-beta"
// Install http-server-sim-client as a Cake Addin #addin nuget:?package=http-server-sim-client&version=1.3.0.523-beta&prerelease // Install http-server-sim-client as a Cake Tool #tool nuget:?package=http-server-sim-client&version=1.3.0.523-beta&prerelease
http-server-sim
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:
- Create a rule file defining conditions and a response message.
- Place the rule file in the appropriate directory.
- 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. |
--DefaultDelayMin <value> |
The delay (in milliseconds) before sending a default response message when no matching rule for the request is found. Default: 0. |
--DefaultDelayMax <value> |
The maximum delay (in milliseconds) before sending a default response message when no matching rule for the request is found. |
When --DefaultDelayMax is specified, the actual delay will be a random value between --DefaultDelayMin and --DefaultDelayMax. | |
--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
- Method Conditions: These specify the HTTP method (e.g.,
GET
,POST
) that the request must match. - URL Path Conditions: These specify the URL path that the request must match.
The supported operators are: Equals
, StartWith
, and Contains
Rule 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"
}
Rule delays
When http-server-sim identifies a matching rule for a request, it applies any specified delay associated with that rule.
A delay can be specified in the delay
section of a rule, though it's optional. If not provided, the default delay is 0 milliseconds.
Delays are expressed in milliseconds.
Example of setting a delay of 5 seconds.
"delay": {
"min": 5000
}
Example of setting a random delay between 1 and 10 seconds.
"delay": {
"min": 1000,
"max": 10000
}
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 | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- FluentAssertions (>= 6.12.1)
- System.Text.Json (>= 8.0.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.3.0.523-beta | 113 | 10/16/2024 |
1.3.0.513-beta | 68 | 10/15/2024 |
1.3.0.489-beta | 74 | 9/12/2024 |
1.2.0.471 | 100 | 8/27/2024 |
1.1.0.464 | 111 | 8/14/2024 |