Files
WireMock.Net/test/WireMock.Net.Tests/StatefulBehaviorTests.cs
Stef Heyenrath a292f28dda Version 2.x (#1359)
* Version 2.x

* Setup .NET 9

* 12

* cleanup some #if for NETSTANDARD1_3

* cleanup + fix tests for net8

* openapi

* NO ConfigureAwait(false) + cleanup

* .

* #endif

* HashSet

* WireMock.Net.NUnit

* HttpContext

* Add WebSockets (#1423)

* Add WebSockets

* Add tests

* fix

* more tests

* Add tests

* ...

* remove IOwin

* -

* tests

* fluent

* ok

* match

* .

* byte[]

* x

* func

* func

* byte

* trans

* ...

* frameworks.........

* jmes

* xxx

* sc

* using var httpClient = new HttpClient();

* usings

* maxRetries

* up

* xunit v3

* ct

* ---

* ct

* ct2

* T Unit

* WireMock.Net.TUnitTests / 10

* t unit first

* --project

* no tunit

* t2

* --project

* --project

* ci -  --project

* publish ./test/wiremock-coverage.xml

* windows

* .

* log

* ...

* log

* goed

* BodyType

* .

* .

* --scenario

* ...

* pact

* ct

* .

* WireMock.Net.RestClient.AwesomeAssertions (#1427)

* WireMock.Net.RestClient.AwesomeAssertions

* ok

* atpath

* fix test

* sonar fixes

* ports

* proxy test

* FIX?

* ---

* await Task.Delay(100, _ct);

* ?

* --project

* Aspire: use IDistributedApplicationEventingSubscriber (#1428)

* broadcast

* ok

* more tsts

* .

* Collection

* up

* .

* 2

* remove nfluent

* <VersionPrefix>2.0.0-preview-02</VersionPrefix>

* ...

* .

* nuget icon

* .

* <PackageReference Include="JmesPath.Net" Version="1.1.0" />

* x

* 500

* .

* fix some warnings

* ws
2026-03-11 17:02:47 +01:00

465 lines
18 KiB
C#

// Copyright © WireMock.Net
using System.Net;
using System.Net.Http;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server;
namespace WireMock.Net.Tests;
public class StatefulBehaviorTests
{
[Fact]
public async Task Scenarios_Should_skip_non_relevant_states()
{
// given
string path = $"/foo_{Guid.NewGuid()}";
var server = WireMockServer.Start();
server
.Given(Request.Create().WithPath(path).UsingGet())
.InScenario("s")
.WhenStateIs("Test state")
.RespondWith(Response.Create());
// when
var response = await new HttpClient().GetAsync("http://localhost:" + server.Ports[0] + path, TestContext.Current.CancellationToken);
// then
response.StatusCode.Should().Be(HttpStatusCode.NotFound);
server.Stop();
}
[Fact]
public async Task Scenarios_Should_process_request_if_equals_state_and_single_state_defined()
{
// Arrange
var cancellationToken = TestContext.Current.CancellationToken;
var path = $"/foo_{Guid.NewGuid()}";
using var server = WireMockServer.Start();
server
.Given(Request.Create().WithPath(path).UsingGet())
.InScenario("s")
.WillSetStateTo("Test state")
.RespondWith(Response.Create().WithBody("No state msg"));
server
.Given(Request.Create().WithPath(path).UsingGet())
.InScenario("s")
.WhenStateIs("Test state")
.RespondWith(Response.Create().WithBody("Test state msg"));
// Act
var responseNoState = await new HttpClient().GetStringAsync(server.Url + path, cancellationToken);
var responseWithState = await new HttpClient().GetStringAsync(server.Url + path, cancellationToken);
// Assert
responseNoState.Should().Be("No state msg");
responseWithState.Should().Be("Test state msg");
}
[Theory]
[InlineData(null, "step 1", "step 2")]
[InlineData("step 2", "step 2", "step 3")]
public async Task Scenarios_Should_ContinueOnCorrectState_WhenStateIsUpdated(string? state, string expected1, string expected2)
{
// Arrange
var cancellationToken = TestContext.Current.CancellationToken;
var path = $"/foo_{Guid.NewGuid()}";
var scenario = "s";
using var server = WireMockServer.Start();
server
.Given(Request.Create().WithPath(path).UsingGet())
.InScenario(scenario)
.WillSetStateTo("step 2")
.RespondWith(Response.Create().WithBody("step 1"));
server
.Given(Request.Create().WithPath(path).UsingGet())
.InScenario(scenario)
.WhenStateIs("step 2")
.WillSetStateTo("step 3")
.RespondWith(Response.Create().WithBody("step 2"));
server
.Given(Request.Create().WithPath(path).UsingGet())
.InScenario(scenario)
.WhenStateIs("step 3")
.RespondWith(Response.Create().WithBody("step 3"));
// Act
var client = server.CreateClient();
var response1 = await client.GetStringAsync(server.Url + path, cancellationToken);
var response2 = await client.GetStringAsync(server.Url + path, cancellationToken);
var response3 = await client.GetStringAsync(server.Url + path, cancellationToken);
server.SetScenarioState(scenario, state);
var responseA = await client.GetStringAsync(server.Url + path, cancellationToken);
var responseB = await client.GetStringAsync(server.Url + path, cancellationToken);
// Assert
response1.Should().Be("step 1");
response2.Should().Be("step 2");
response3.Should().Be("step 3");
responseA.Should().Be(expected1);
responseB.Should().Be(expected2);
}
[Fact]
public async Task Scenarios_With_Same_Path_Should_Use_Times_When_Moving_To_Next_State()
{
// given
var cancellationToken = TestContext.Current.CancellationToken;
const int times = 2;
string path = $"/foo_{Guid.NewGuid()}";
string body1 = "Scenario S1, No State, Setting State T2";
string body2 = "Scenario S1, State T2, End";
var server = WireMockServer.Start();
server
.Given(Request.Create().WithPath(path).UsingGet())
.InScenario(1)
.WillSetStateTo(2, times)
.RespondWith(Response.Create().WithBody(body1));
server
.Given(Request.Create().WithPath(path).UsingGet())
.InScenario(1)
.WhenStateIs(2)
.RespondWith(Response.Create().WithBody(body2));
// when
var client = new HttpClient();
var responseScenario1 = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path, cancellationToken);
var responseScenario2 = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path, cancellationToken);
var responseWithState = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path, cancellationToken);
// then
responseScenario1.Should().Be(body1);
responseScenario2.Should().Be(body1);
responseWithState.Should().Be(body2);
server.Stop();
}
[Fact]
public async Task Scenarios_With_Different_Paths_Should_Use_Times_When_Moving_To_Next_State()
{
// given
var cancellationToken = TestContext.Current.CancellationToken;
const int times = 2;
string path1 = $"/a_{Guid.NewGuid()}";
string path2 = $"/b_{Guid.NewGuid()}";
string path3 = $"/c_{Guid.NewGuid()}";
string body1 = "Scenario S1, No State, Setting State T2";
string body2 = "Scenario S1, State T2, Setting State T3";
string body3 = "Scenario S1, State T3, End";
var server = WireMockServer.Start();
server
.Given(Request.Create().WithPath(path1).UsingGet())
.InScenario("S1")
.WillSetStateTo("T2", times)
.RespondWith(Response.Create().WithBody(body1));
server
.Given(Request.Create().WithPath(path2).UsingGet())
.InScenario("S1")
.WhenStateIs("T2")
.WillSetStateTo("T3", times)
.RespondWith(Response.Create().WithBody(body2));
server
.Given(Request.Create().WithPath(path3).UsingGet())
.InScenario("S1")
.WhenStateIs("T3")
.RespondWith(Response.Create().WithBody(body3));
// when
var client = new HttpClient();
var t1a = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path1, cancellationToken);
var t1b = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path1, cancellationToken);
var t2a = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path2, cancellationToken);
var t2b = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path2, cancellationToken);
var t3 = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path3, cancellationToken);
// then
t1a.Should().Be(body1);
t1b.Should().Be(body1);
t2a.Should().Be(body2);
t2b.Should().Be(body2);
t3.Should().Be(body3);
server.Stop();
}
[Fact]
public async Task Scenarios_Should_Respect_Int_Valued_Scenarios_and_States()
{
// given
var cancellationToken = TestContext.Current.CancellationToken;
string path = $"/foo_{Guid.NewGuid()}";
var server = WireMockServer.Start();
server
.Given(Request.Create().WithPath(path).UsingGet())
.InScenario(1)
.WillSetStateTo(2)
.RespondWith(Response.Create().WithBody("Scenario 1, Setting State 2"));
server
.Given(Request.Create().WithPath(path).UsingGet())
.InScenario(1)
.WhenStateIs(2)
.RespondWith(Response.Create().WithBody("Scenario 1, State 2"));
// when
var responseIntScenario = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path, cancellationToken);
var responseWithIntState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path, cancellationToken);
// then
responseIntScenario.Should().Be("Scenario 1, Setting State 2");
responseWithIntState.Should().Be("Scenario 1, State 2");
server.Stop();
}
[Fact]
public async Task Scenarios_Should_Respect_Mixed_String_Scenario_and_Int_State()
{
// given
var cancellationToken = TestContext.Current.CancellationToken;
string path = $"/foo_{Guid.NewGuid()}";
var server = WireMockServer.Start();
server
.Given(Request.Create().WithPath(path).UsingGet())
.InScenario("state string")
.WillSetStateTo(1)
.RespondWith(Response.Create().WithBody("string state, Setting State 2"));
server
.Given(Request.Create().WithPath(path).UsingGet())
.InScenario("state string")
.WhenStateIs(1)
.RespondWith(Response.Create().WithBody("string state, State 2"));
// when
var responseIntScenario = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path, cancellationToken);
var responseWithIntState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path, cancellationToken);
// then
responseIntScenario.Should().Be("string state, Setting State 2");
responseWithIntState.Should().Be("string state, State 2");
server.Stop();
}
[Fact]
public async Task Scenarios_Should_Respect_Mixed_Int_Scenario_and_String_Scenario_and_String_State()
{
// given
var cancellationToken = TestContext.Current.CancellationToken;
string path = $"/foo_{Guid.NewGuid()}";
var server = WireMockServer.Start();
server
.Given(Request.Create().WithPath(path).UsingGet())
.InScenario(1)
.WillSetStateTo("Next State")
.RespondWith(Response.Create().WithBody("int state, Setting State 2"));
server
.Given(Request.Create().WithPath(path).UsingGet())
.InScenario("1")
.WhenStateIs("Next State")
.RespondWith(Response.Create().WithBody("string state, State 2"));
// when
var responseIntScenario = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path, cancellationToken);
var responseWithIntState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path, cancellationToken);
// then
responseIntScenario.Should().Be("int state, Setting State 2");
responseWithIntState.Should().Be("string state, State 2");
server.Stop();
}
[Fact]
public async Task Scenarios_TodoList_Example()
{
// Arrange
var cancelationToken = TestContext.Current.CancellationToken;
var server = WireMockServer.Start();
var client = server.CreateClient();
server
.Given(Request.Create().WithPath("/todo/items").UsingGet())
.InScenario("To do list")
.WillSetStateTo("TodoList State Started")
.RespondWith(Response.Create().WithBody("Buy milk"));
server
.Given(Request.Create().WithPath("/todo/items").UsingPost())
.InScenario("To do list")
.WhenStateIs("TodoList State Started")
.WillSetStateTo("Cancel newspaper item added")
.RespondWith(Response.Create().WithStatusCode(201));
server
.Given(Request.Create().WithPath("/todo/items").UsingGet())
.InScenario("To do list")
.WhenStateIs("Cancel newspaper item added")
.RespondWith(Response.Create().WithBody("Buy milk;Cancel newspaper subscription"));
server.Scenarios.Any().Should().BeFalse();
// Act and Assert
var getResponse1 = await client.GetStringAsync("/todo/items", cancelationToken);
getResponse1.Should().Be("Buy milk");
server.Scenarios["To do list"].Name.Should().Be("To do list");
server.Scenarios["To do list"].NextState.Should().Be("TodoList State Started");
server.Scenarios["To do list"].Started.Should().BeTrue();
server.Scenarios["To do list"].Finished.Should().BeFalse();
var postResponse = await client.PostAsync("/todo/items", new StringContent("Cancel newspaper subscription"), cancelationToken);
postResponse.StatusCode.Should().Be(HttpStatusCode.Created);
server.Scenarios["To do list"].Name.Should().Be("To do list");
server.Scenarios["To do list"].NextState.Should().Be("Cancel newspaper item added");
server.Scenarios["To do list"].Started.Should().BeTrue();
server.Scenarios["To do list"].Finished.Should().BeFalse();
string getResponse2 = await client.GetStringAsync("/todo/items", cancelationToken);
getResponse2.Should().Be("Buy milk;Cancel newspaper subscription");
server.Scenarios["To do list"].Name.Should().Be("To do list");
server.Scenarios["To do list"].NextState.Should().BeNull();
server.Scenarios["To do list"].Started.Should().BeTrue();
server.Scenarios["To do list"].Finished.Should().BeTrue();
server.Stop();
}
[Fact]
public async Task Scenarios_TodoList_WithSetState()
{
// Arrange
var cancelationToken = TestContext.Current.CancellationToken;
var scenario = "To do list";
using var server = WireMockServer.Start();
var client = server.CreateClient();
server
.Given(Request.Create().WithPath("/todo/items").UsingGet())
.InScenario(scenario)
.WhenStateIs("Buy milk")
.RespondWith(Response.Create().WithBody("Buy milk"));
server
.Given(Request.Create().WithPath("/todo/items").UsingGet())
.InScenario(scenario)
.WhenStateIs("Cancel newspaper")
.RespondWith(Response.Create().WithBody("Buy milk;Cancel newspaper subscription"));
// Act and Assert
server.SetScenarioState(scenario, "Buy milk");
server.Scenarios[scenario].Should().BeEquivalentTo(new { Name = scenario, NextState = "Buy milk" });
var getResponse1 = await client.GetStringAsync("/todo/items", cancelationToken);
getResponse1.Should().Be("Buy milk");
server.SetScenarioState(scenario, "Cancel newspaper");
server.Scenarios[scenario].Name.Should().Be(scenario);
server.Scenarios[scenario].Should().BeEquivalentTo(new { Name = scenario, NextState = "Cancel newspaper" });
var getResponse2 = await client.GetStringAsync("/todo/items", cancelationToken);
getResponse2.Should().Be("Buy milk;Cancel newspaper subscription");
}
[Fact]
public void Scenarios_TodoList_WithSetStateToNull_ShouldThrowException()
{
// Arrange
var scenario = "To do list";
using var server = WireMockServer.Start();
var client = server.CreateClient();
server
.Given(Request.Create().WithPath("/todo/items").UsingGet())
.InScenario(scenario)
.WhenStateIs("Buy milk")
.RespondWith(Response.Create().WithBody("Buy milk"));
server
.Given(Request.Create().WithPath("/todo/items").UsingGet())
.InScenario(scenario)
.WhenStateIs("Cancel newspaper")
.RespondWith(Response.Create().WithBody("Buy milk;Cancel newspaper subscription"));
// Act
server.SetScenarioState(scenario, null);
var action = async () => await client.GetStringAsync("/todo/items");
// Assert
action.Should().ThrowAsync<HttpRequestException>();
}
[Fact]
public async Task Scenarios_Should_process_request_if_equals_state_and_multiple_state_defined()
{
// Assign
var cancelationToken = TestContext.Current.CancellationToken;
var server = WireMockServer.Start();
server
.Given(Request.Create().WithPath("/state1").UsingGet())
.InScenario("s1")
.WillSetStateTo("Test state 1")
.RespondWith(Response.Create().WithBody("No state msg 1"));
server
.Given(Request.Create().WithPath("/foo1X").UsingGet())
.InScenario("s1")
.WhenStateIs("Test state 1")
.RespondWith(Response.Create().WithBody("Test state msg 1"));
server
.Given(Request.Create().WithPath("/state2").UsingGet())
.InScenario("s2")
.WillSetStateTo("Test state 2")
.RespondWith(Response.Create().WithBody("No state msg 2"));
server
.Given(Request.Create().WithPath("/foo2X").UsingGet())
.InScenario("s2")
.WhenStateIs("Test state 2")
.RespondWith(Response.Create().WithBody("Test state msg 2"));
// Act and Assert
string url = "http://localhost:" + server.Ports[0];
var responseNoState1 = await new HttpClient().GetStringAsync(url + "/state1", cancelationToken);
responseNoState1.Should().Be("No state msg 1");
var responseNoState2 = await new HttpClient().GetStringAsync(url + "/state2", cancelationToken);
responseNoState2.Should().Be("No state msg 2");
var responseWithState1 = await new HttpClient().GetStringAsync(url + "/foo1X", cancelationToken);
responseWithState1.Should().Be("Test state msg 1");
var responseWithState2 = await new HttpClient().GetStringAsync(url + "/foo2X", cancelationToken);
responseWithState2.Should().Be("Test state msg 2");
server.Stop();
}
}