GithubHelp home page GithubHelp logo

mbdotnet's Introduction

ko-fi

MbDotNet

A .NET client library for interacting with Mountebank. This project aims to reduce the amount of Mountebank knowledge required to create and configure imposters through a natural language interface.

A simple example:

await _client.CreateHttpImposter(4545, "My Imposter", imposter =>
{
	imposter.AddStub()
		.OnPathAndMethodEqual("/customers/123", Method.Get)
		.ReturnsXml(HttpStatusCode.OK, new Customer { Email = "[email protected]" });
});

To get started, read the documentation here.

NuGet Package

The library is available for install as a NuGet package.

https://www.nuget.org/packages/MbDotNet

The project currently targets .NET Standard 1.3, which is compatible with .NET Framework 4.6. If you need to use it in a project targeting an older framework version, such as .NET Framework 4.5, please use version 3.x of the package.

Upgrading from v4 (or earlier) to v5

There were a handful of breaking changes in v5 of the library. If you are planning to upgrade to v5, please take a look at the migration guide.

Unsupported Functionality

The following Mountebank functionality is not yet supported:

Pull requests are always welcome.

Development

Prerequisites

The following items are necessary in order to build and test the project:

  • .NET SDK 6.0
  • Mountebank or Docker Compose

Building

To build the project, run the following from the root directory:

dotnet build

Testing

To run all tests, run the following from the root directory:

dotnet test

This includes a set of acceptance tests that run against an actual Mountebank instance. In order for those tests to succeed, Mountebank will need to be run with the --allowInjection and --debug options provided. See http://www.mbtest.org/docs/api/overview#get-imposter.

If you would prefer to run Mountebank via docker, please execute the following command from the root directory: docker compose up

If you would like to just run the unit tests (which do not require Mountebank), run the following:

dotnet test --filter Category=Unit

Similarly, you can filter to only the acceptance tests using --filter Category=Acceptance.

mbdotnet's People

Contributors

adrianbontea avatar drakocds avatar ds-mattherman avatar ihramtsov avatar kichiginatatiana avatar kiwiprog avatar lucasbode avatar mabead avatar mattherman avatar mcosta91 avatar nrjohnstone avatar playaroundhub avatar pseudodream avatar putnap avatar roundrobinquantum avatar superdrew avatar tgmike avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mbdotnet's Issues

RestSharpSigned dependency conflicts with any RestSharp dependencies

When using v2.1.0, which is now signed and relies on RestSharpSigned instead of RestSharp, I run into issues utilizing the package in a project that has dependencies on the unsigned version of RestSharp. They appear to conflict since both assemblies are RestSharp but the signed version of the assembly in package 105.2.3 has a version of 100.0.0 while the unsigned version of the assembly in package 105.2.3 has a version of 105.2.3.

I plan to investigate how to resolve this issue. If it seems like this may be unavoidable, I will consider no longer publishing the signed assemblies.

Add support for form content in HttpPredicateFields

When sending form content using the application/x-www-form-urlencoded content type, the body containing the content is a string in a form such as:

parameter1=value1&parameter2=value2

To intercept this with a Mountebank predicate using MbDotNet, it is possible to do the following:

var predicate = new HttpPredicateFields
{
    RequestBody = "parameter1=value1&parameter2=value2"
};

However, because of the nature of form content which is created using a dictionary, we are not guaranteed that all of the parameters will be formed into a string in the order that our predicate specifies. For example:

var requestContent = new Dictionary<string, string>
{
    ["parameter1"] = "value1",
    ["parameter2"] = "value2"
};

var httpMessage = new HttpRequestMessage();
httpMessage.Content = new FormUrlEncodedContent(requestContent);

As per this Mountebank PR and documentation (see Http Requests), support has been added to specify form content as key value pairs in Mountebank. In Mountebank JSON, the predicate would look like:

{
    "matches": {
        "form": {
            "parameter1": "value1",
            "parameter2": "value2"
        },
        "headers": {
            "Content-Type": "application/x-www-form-urlencoded"
        }
    },
    "caseSensitive": false
}

The HttpPredicateFields class in MbDotNet does not currently have support to add this natively. In a project I worked on, I have been able to extend the class and add support for form content via MbDotNet successfully.

I would like to see this as part of the MbDotNet library so that others may benefit from it and I'm happy to make the PR to support this.

HttpClientWrapper should be internal

The HttpClientWrapper type was made public by mistake and should be made internal. Doing so is technically a breaking change (although I would hope nobody was utilizing that class) so it will need to wait until a new major version is ready to be published.

Update client to include newer API methods

There have been a few new API methods added to mountebank since this library was created. An issue has already been created for adding the ability to update imposters (#29) but there are a couple more that could be added. Adding this issue for a place to track that.

Capability Supported? Planned Notes
Get entry hypermedia ✔️
Create a single imposter ✔️
Get a single imposter ✔️
Add a stub to an existing imposter ✔️
Overwrite a stub of an existing imposter ✔️
Overwrite all stubs of an existing imposter ✔️
Remove a stub of an existing imposter ✔️
Delete a single imposter ✔️
Delete saved proxy responses from an imposter ✔️
Overwrite all imposters with a new set of imposters
Get a list of all imposters ✔️
Delete all imposters ✔️
Get mountebank configuration and process information ✔️
Get the logs ✔️

This list is up to date as of mountebank v2.8.2 and taken from this page.

Support "allowCORS" Imposter Creation Parameter

Currently there is no corresponding parameter in the HttpImposter and HttpsImposter constructors for the allowCORS parameter, documented here:

http://www.mbtest.org/docs/protocols/http

Is this something that could be added, and if so would the best place to add it be in the constructor as an optional parameter? I'd be happy to take a crack at it if that's the right place to introduce it.

Body as String, not Json object

MbDotNet 4.3.0(Nuget)

I create imposter:
var complexPredicateFields = new HttpPredicateFields
{
Method = Method.Post,
Path = "/bm-reportbcsrus/brokerReportRUS/reportData",
Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } }
};
var complexPredicate = new EqualsPredicate(complexPredicateFields);
var bodyPredicateFields = new HttpPredicateFields()
{
RequestBody = "{ "title": "Harry Potter" }"
};
var bodyPredicate = new EqualsPredicate(bodyPredicateFields, true, "$!", null);
_imposter.AddStub().On(complexPredicate).On(bodyPredicate).ReturnsJson(HttpStatusCode.OK, response);
_mountebankClient.Submit(_imposter);

Then result imposter is:
{
"predicates": [
{
"equals": {
"path": "/bm-reportbcsrus/brokerReportRUS/reportData",
"method": "POST",
"headers": {
"Content-Type": "application/json"
}
},
"caseSensitive": false
},
{
"equals": {
"body": "{ title: Harry Potter }"//why it is in quotes?
},
"caseSensitive": true,
"except": "$!"
}
],
}

So, i want this:
"equals": { "body": { "title": "Harry Potter" } },
but i got this:
"equals": { "body": "{ title: Harry Potter }" }

I want use json object in body, not string

gRPC Mock Servers with MbDotNet?

I'm looking for a way to speed up iterating on tests with a third party that uses gRPC for their public API. Their API is kind of slow and prone to failing mid-stream.

It would be awesome if MbDotNet could be explained to me in a way I could use it to isolate a couple of response sequences from their servers and replay them as integration test data.

Happy to donate several cups of coffee to you for help.

Remove `CreateXYZImposter` methods from `MountebankClient`

There have been other breaking changes (such as removal of non-async client methods) that will require pushing a v5 of the library. Due to this, I am looking at other mistakes I've made that would require breaking changes. One of those mistakes is that addition of the CreateXYZImposter methods on the MountebankClient class that serve as factory methods for the imposters. There is no real reason why these factory methods are necessary since their signatures are essentially identical to the imposters' constructors. They also seem to confuse users since they sometimes expect those methods to have actually submitted the new imposter to mountebank.

In order to remedy this, I am considering removing them altogether and just expecting users to create the imposters themselves via the constructors.

Maintaining internal list of imposters makes the client tricky to use

The API is not very clear that behind the scenes it is maintaining a list of imposters you have created and only submitting the request to Mb if an imposter exists already.

This makes it impossible to delete and imposter before creating one, if for example you want your acceptance to test to be certain that a particular imposter does not exist.

I have a PR that does the following

  1. Introduces and acceptance test console app that can run real scenarios against mb, rather than relying on unit tests with mocks

  2. moves the delete imposter call to the proxy outside the check for the internal imposters list

How to use the "add stub" API on an existing imposter

I have an existing http imposter that is already running in mountebank. I would like to add stub to this imposter by calling the "add stub" API: http://www.mbtest.org/docs/api/overview#add-stub.

I looked in the code of MbDotNet but I couldn't find a way to just add a stub to an existing imposter. I just found way to either create or update the imposter.

Could you please tell me if I looked in the wrong place or I could call this "add stub" API if this feature exists?

Support Dynamic Ports

Mountebank allows you to create imposters without a port. A random port will be assigned which can then be retrieved from the POST response or a subsequent GET. The client should also allow this as well.

DAMP versus DRY in Acceptance Tests

I have no where else to raise or discuss this with you so I'll need to raise it as an issue here

Tests should be DAMP where possible to aid in understanding, not DRY.

There is no point moving the private methods that "seem" to be repeated code among the tests are they are merely a means of fluently expressing the intent of the public method by keeping all of the statements at the same abstraction level.

Improve documentation

I am really enjoying using MbDotNet but as I get into more difficult cases I am having trouble with working out what to use in those cases. In particular I am having trouble with predicates e.g. what's the difference between a MatchesPredicate and an EqualsPredicate etc.

An example I'm trying to achieve is for the predicate to not match if a query string is added that is not expected.

Anything you could add to clarify would be much appreciated.

Support imposter updates/replacements

Mountebank allows you to completely replace an existing imposter through a PUT request to the imposters resource. Since it deletes the imposter and replaces it with the new one, this can also be used to update an imposter, for example if you added a stub after already submitting it.

PendingSubmission property is no longer useful

With recent updates the the client API around submission of imposters (#11), the Imposter.PendingSubmission attribute is no longer useful. The only way to get an imposter into the collection maintained by the client is to submit it, which results in PendingSubmission being set to false. There will never be any imposters in that collection that have PendingSubmission equal to true.

I suggest removing the property altogether. Since this is a breaking change, it should be done before v3 is published.

Delete Imposters By Name

Hi. Greate package thank you!!!

Now that we can create imposters by name, would it be possible to delete them by name also?
Ie. same instance, same port, multiple named imposters, but delete only 1 of them?

public async Task<HttpImposter> CreateHttpImposterAsync(
  int? port,
  string name,
  Action<HttpImposter> imposterConfigurator,
  CancellationToken cancellationToken = default (CancellationToken))

Support query parameters with the same parameter key

It is possible to have query parameters that share the same key for example: https://example.com/get?param1=test1&param1=test2&param1=test3

It would be nice for the client to support this as it does not currently since HttpPredicateFields : https://github.com/mattherman/MbDotNet/blob/master/MbDotNet/Models/Predicates/Fields/HttpPredicateFields.cs uses a Dictionary for query parameters.

I know this may be a little controversial since there is not set HTTP standard on how to deal with multiple parameters with the same key but it looks like Microsoft are consistent on how it is parsed for example - https://stackoverflow.com/questions/24059773/correct-way-to-pass-multiple-values-for-same-parameter-name-in-get-request

One way to preserve the same outcomes without breaking changes could be to change it from a IDictionary<string, object> to a IEnumerable<KeyValuePair<string, object>>

Add async API to nuget package

For now the last available version is 4.3.1. It doesn't contain async API methods, instead of it there are Task.Result and Task.Wait() invocations. Such approach could cause a deadlock. As I see it is fixed in the master branch, so could you please release a new nuget package with async API

Reject HTTPS imposters with invalid key/cert

Mountebank requires the key and cert of an HTTPS imposter to be a valid PEM-formatted string. While the docs for the CreateHttpsImposter method call this out, the method does not do any validation. The client should be updated to validate and reject any requests to create those imposters if they do not have valid key/cert.

Fetching imposters

Hi, I was wondering if you've considered adding support for retrieving replayable imposters? E.g. GET /imposters?replayable=true. I am facing an issue where I need to be able to persist the request/responses of a mountebank instance that has been in proxy mode and later re-use that. If you have no plans for that, would you accept a PR adding support? I would rather support this project than make my own implementation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.