All Projects → paulmorrishill → FluentSimulator

paulmorrishill / FluentSimulator

Licence: MIT license
A fluent syntax .NET REST/HTTP API simulator for automated unit and UI testing.

Programming Languages

C#
18002 projects

Projects that are alternatives of or similar to FluentSimulator

Generator Http Fake Backend
Yeoman generator for building a fake backend by providing the content of JSON files or JavaScript objects through configurable routes.
Stars: ✭ 49 (+113.04%)
Mutual labels:  restful, mocking
MockitoIn28Minutes
Learn Mockito from In28Minutes
Stars: ✭ 95 (+313.04%)
Mutual labels:  mocking, unit
ineeda
Mocking library for TypeScript and JavaScript using Proxies!
Stars: ✭ 53 (+130.43%)
Mutual labels:  mocking, unit
Http Fake Backend
Build a fake backend by providing the content of JSON files or JavaScript objects through configurable routes.
Stars: ✭ 253 (+1000%)
Mutual labels:  restful, mocking
Moonwards-Virtual-Moon
Development continues on Unreal, in the MoonwardsUE repository
Stars: ✭ 97 (+321.74%)
Mutual labels:  simulator
mockfn
A mocking library for Clojure.
Stars: ✭ 18 (-21.74%)
Mutual labels:  mocking
laika
Log, test, intercept and modify Apollo Client's operations
Stars: ✭ 99 (+330.43%)
Mutual labels:  mocking
mock-alchemy
SQLAlchemy mock helpers.
Stars: ✭ 44 (+91.3%)
Mutual labels:  mocking
showdown-battle-bot
Socket Battle Bot for Pokemon Showdown (http://pokemonshowdown.com/)
Stars: ✭ 19 (-17.39%)
Mutual labels:  simulator
TIDAL
Reverse engineering the TIDAL API. OAuth2 (RFC 8628 & RFC 6749) and (nearly) all endpoints
Stars: ✭ 78 (+239.13%)
Mutual labels:  restful
WebRISC-V
WebRISC-V: A Web-Based Education-Oriented RISC-V Pipeline Simulation Environment [PHP]
Stars: ✭ 74 (+221.74%)
Mutual labels:  simulator
mima
MIninmal MAchine Assembler and Simulator
Stars: ✭ 19 (-17.39%)
Mutual labels:  simulator
coord-sim
Lightweight flow-level simulator for inter-node network and service coordination (e.g., in cloud/edge computing or NFV).
Stars: ✭ 33 (+43.48%)
Mutual labels:  simulator
Assume
Easy Response Mocking for Retrofit using annotations
Stars: ✭ 25 (+8.7%)
Mutual labels:  mocking
device-simulator
基于netty的设备模拟器,模拟设备消息收发,压力测试。
Stars: ✭ 35 (+52.17%)
Mutual labels:  simulator
heimdall
Painless OAuth 2.0 Server for CodeIgniter 4 🔥
Stars: ✭ 36 (+56.52%)
Mutual labels:  restful
ravel
A RISC-V simulator
Stars: ✭ 24 (+4.35%)
Mutual labels:  simulator
koa-better-router
❤️ Stable and lovely router for `koa`, using `path-match`. Foundation for building powerful, flexible and RESTful APIs easily.
Stars: ✭ 88 (+282.61%)
Mutual labels:  restful
java-crud-api
No description or website provided.
Stars: ✭ 24 (+4.35%)
Mutual labels:  restful
open-simulator
K8s cluster simulator for capacity planning
Stars: ✭ 158 (+586.96%)
Mutual labels:  simulator

FluentSimulator

FluentSimulator is a .Net HTTP API simulator library that is extremely versitile and unassuming.

There are 2 main use cases for FluentSimulator.

  • Simulating a 3rd party API to unit test your code that interacts with that API
  • Mocking out REST or other APIs during automated browser based testing using something like selenium - useful for light weight single page application testing.

Build status AppVeyor tests NuGet

Usage

Using the simulator is designed to be extremely easy.

//Initialise the simulator
var simulator = new FluentSimulator("http://localhost:8080/");
simulator.Start();

//Setup your simulated routes and responses
simulator.Get("/my/route").Responds("Some example content here");

//Now make an HTTP request using whatever means
//GET http://localhost:8080/my/route
//200 Some example content here

Make sure to shutdown the simulator at the end of your unit test (usually in a teardown method) - this will prevent subsequent tests failing on the port being in use.

[TearDown]
public void TearDown()
{
   //Stop the simulator
   simulator.Stop();  
}

Request matching

The simulator can be configured in a few different ways to choose the appropriate response to requests.

Simple requests

Simple plain text path matching can be done with the specific verb methods. If the status code is not specified the simulator returns 200.

// Match http://localhost:8080/test
simulator.Post("/test").Responds("Hello World!");
simulator.Get("/test").Responds("Hello World!");
simulator.Delete("/test").Responds("Hello World!");
simulator.Head("/test").Responds("Hello World!");
simulator.Merge("/test").Responds("Hello World!");
simulator.Options("/test").Responds("Hello World!");
simulator.Patch("/test").Responds("Hello World!");
simulator.Put("/test").Responds("Hello World!");
simulator.Post("/").Responds("Hello World!");
    
// Match GET http://localhost:8080/some/extended/path/here.html
simulator.Get("/some/extended/path/here.html").Responds("Hello World!");

Regex matching

You can match additionally by regex on any of the verb methods by appending the .MatchingRegex() call.

// Match on Regex
// e.g. GET http://localhost:8080/user/42/profile
simulator.Get("/user/[0-9]+/profile")
         .MatchingRegex()   
         .Responds("Super cool profile data")

Matching on query parameters

You can also match on query parameters using the WithParameter method.

  • Parameter order does not matter
  • Parameters are case sensitive for both key and value
  • Query parameters should be passed in raw - the simulator deals with URL decoding
// Match on query parameters
// e.g. GET http://localhost:8080/viewprofile.php?id=123
simulator.Get("/viewprofile.php")
         .WithParameter("id", "123")
         .Responds("Some profile stuff");

 // Query parameters with special characters
 // e.g. GET http://localhost:8080/viewprofile.php?id=SOME-%C2%A3%24%25%5E%26-ID
 simulator.Get("/viewprofile.php")
          .WithParameter("id", "SOME-£$%^&-ID")
          .Responds("OK");

Non matching requests

Any request that does not match any configured responses will return a 501 Not Implemented status code and an empty response body.

Responding to requests

The simulator can be very useful in testing outputs that aren't easy to create reliably on demand using real endpoints.

Status codes

Want to see how your code handles 500 server errors, or 404s?

simulator.Get("/my/route").Responds().WithCode(500);
simulator.Get("/employee/44").Responds().WithCode(404);

Headers

Arbitrary headers can be appended to the response.

simulator.Get("/employee/123")
         .Responds("{}")
         .WithHeader("Content-Type", "application/json")
         .WithHeader("X-Powered-By", "Rainbows and sunshine");

Cookies

You can send cookies.

simulator.Post("/authenticate")
         .Responds()
         .WithCookie(new Cookie("Token", "ABCDEF"));

Slow responses

You can test how your code handles slow server replies.

simulator.Get("/my/route").Responds("Final output").Delay(TimeSpan.FromSeconds(30));

Indefinitely suspend responses at runtime

You can check that your webpage correctly displays loading messages or spinners.

var route = simulator.Get("/employee/1").Responds("John Smith");
//Navigate to your page using selenium
route.Pause();
//Click "John Smith"
//Assert page shows "Loading employee details..."
route.Resume();
//Assert page shows the employee information

Serialize objects

You can return objects through the simulator and they will be converted to JSON before being sent.

simulator.Put("/employee/1").Responds(new EmployeeModel());

Configuring the serializer

Internally the simulator uses the Newtonsoft Json.NET library you can pass in your own serializer settings.

var simulator = new FluentSimulator("http://localhost:8080/", new JsonSerialiserSettings());

Asserting on requests

In addition to configuring the responses to specific URLs you can assert that the request contained all the information you're expecting.

simulator.Post("/post").Responds("OK");
//POST http://localhost/post

var requests = simulator.ReceivedRequests;
var sentAuthHeader = requests[0].Headers["Authorization"]
//Assert sentAuthHeader is correct

//Received requests is an list of ReceivedRequest which has the following data
public class ReceivedRequest
{
    public Uri Url { get; }
    public string HttpMethod { get; }
    public Encoding ContentEncoding { get; }
    public string[] AcceptTypes { get; }
    public string ContentType { get; }
    public NameValueCollection Headers { get; }
    public CookieCollection Cookies { get; }
    public NameValueCollection QueryString { get; }
    public string RawUrl { get; }
    public string UserAgent { get; }
    public string[] UserLanguage { get; }
    public string RequestBody { get; }
    public DateTime TimeOfRequest { get; }
}

Deserializing requests

You can also deserialize the request using the BodyAs<T> method on the ReceivedRequest object.

simulator.Post("/employee").Responds("OK");
//POST http://localhost/post

var requests = simulator.ReceivedRequests;
var sentEmployee = requests[0].BodyAs<EmployeeModel>();

Assert.AreEqual(sentEmployee.FirstName, "John");

Contributing

Contributing to this project is very easy, fork the repo and start coding. Please make sure all changes are unit tested, have a look at the existing unit tests to get an idea of how it works.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].