Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Option to add Interceptors on Client Level #2118

Merged
merged 36 commits into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ef1dddd
feature: Added Implementation for Interceptors
fseidl-bauradar Apr 4, 2023
b8d7ec8
feature: Added Interfaces for Interceptors
fseidl-bauradar Apr 4, 2023
38450ff
Merge branch 'restsharp:dev' into dev
fseidl-bauradar Apr 4, 2023
25f5d65
fix: Corrected Comment
fseidl-bauradar Apr 4, 2023
85b6c79
fix: Configured to wait for result
fseidl-bauradar Apr 4, 2023
9d7b59f
refactor: Renamed Class name to go allong with Class Name conventions
fseidl-bauradar Apr 4, 2023
86772f5
Update RestSharp.sln
fseidl-bauradar Apr 4, 2023
651dabc
Merge branch 'restsharp:dev' into dev
fseidl-bauradar Apr 4, 2023
5c91edd
Removed ConsoleTest from Repository
fseidl-bauradar Apr 4, 2023
b9f4082
Feature: Added Base Interceptor to simplify definition of Interceptors
fseidl-bauradar Apr 4, 2023
b7ed190
Merge branch 'restsharp:dev' into dev
fseidl-bauradar Apr 4, 2023
fa2662e
Fix: Added virtual keyword to allow overriding the functions in deriv…
fseidl-bauradar Apr 4, 2023
6241787
Synchronized Fork with RestSharp Repository
fseidl-bauradar Apr 19, 2023
1cd427a
Solved Merge conflict
fseidl-bauradar Apr 19, 2023
afb6ff3
refactor: Removed Interfaces
fseidl-bauradar May 4, 2023
56086d6
refactor: Removed Interfaces
fseidl-bauradar May 4, 2023
a13ec64
refactor: Moved to Abstract Base Class
fseidl-bauradar May 4, 2023
7d26494
refactor: Use Base class as Element
fseidl-bauradar May 4, 2023
a930f98
fix: Added UnitTest to Dependencies
fseidl-bauradar May 4, 2023
9312863
sychronized with upstream
fseidl-bauradar May 4, 2023
adf131d
refactor: Adde nuget.config to gitignore
fseidl-bauradar May 4, 2023
b31aee4
Merge branch 'restsharp:dev' into dev
fseidl-bauradar May 12, 2023
7cec99f
Merge branch 'restsharp:dev' into dev
fseidl-bauradar Jun 19, 2023
565f72e
refactor: Moved OnBeforeDeserialization into async context one layer …
fseidl-bauradar Jun 28, 2023
f5616cd
refactor: Moved Interceptor Calls and surrounding Code out of try,cat…
fseidl-bauradar Jun 28, 2023
c26b6a4
refactor: Added Test for Interceptor
fseidl-bauradar Jun 28, 2023
36e688f
refactor: Adde global.json to .gitignore
fseidl-bauradar Jun 28, 2023
25b2fb4
refactor: ConfigureAwait(false) not needed to return to origin thread
fseidl-bauradar Jun 28, 2023
6f39867
refactor: Remove global.json from gitignore
fseidl-bauradar Jul 19, 2023
721a9b0
refactor: Changed back Project guid
fseidl-bauradar Jul 19, 2023
08f9be4
refactor: Removed System.Threading.Tasks depencency from RestSharp.cs…
fseidl-bauradar Jul 19, 2023
ac79e2b
refactor: Removed xunig.assert depencency from RestSharp.InteractiveT…
fseidl-bauradar Jul 19, 2023
4ad71a4
refactor: Readded global.json
fseidl-bauradar Jul 19, 2023
901e5c3
refactor: Undo renaming class user to User
fseidl-bauradar Jul 19, 2023
c2d15b7
Merge branch 'dev' of https://github.com/fseidl-bauradar/RestSharp in…
fseidl-bauradar Jul 19, 2023
163ce73
Merge branch 'dev' into dev
alexeyzimarev Sep 13, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
packages
packages/
nuget.config


#ignore thumbnails created by windows
Thumbs.db
Expand Down
30 changes: 30 additions & 0 deletions RestSharp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,36 @@ Global
{FE778406-ADCF-45A1-B775-A054B55BFC50}.Release|x64.Build.0 = Release|Any CPU
{FE778406-ADCF-45A1-B775-A054B55BFC50}.Release|x86.ActiveCfg = Release|Any CPU
{FE778406-ADCF-45A1-B775-A054B55BFC50}.Release|x86.Build.0 = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|Any CPU.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|Any CPU.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|ARM.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|ARM.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|Mixed Platforms.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|Mixed Platforms.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|x64.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|x64.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|x86.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug.Appveyor|x86.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|ARM.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|ARM.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|x64.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|x64.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|x86.ActiveCfg = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Debug|x86.Build.0 = Debug|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|Any CPU.Build.0 = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|ARM.ActiveCfg = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|ARM.Build.0 = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|x64.ActiveCfg = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|x64.Build.0 = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|x86.ActiveCfg = Release|Any CPU
{5E8D472F-5A12-4CD8-8DBE-E3F6E0F76798}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
2 changes: 1 addition & 1 deletion gen/SourceGenerator/SourceGenerator.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
Expand Down
7 changes: 7 additions & 0 deletions global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"sdk": {
"version": "7.0.0",
"rollForward": "latestMajor",
"allowPrerelease": false
}
}
57 changes: 57 additions & 0 deletions src/RestSharp/Interceptors/Interceptor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) .NET Foundation and Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

namespace RestSharp.Interceptors;

/// <summary>
/// Base Interceptor
/// </summary>
public abstract class Interceptor {
/// <summary>
/// Intercepts the request before serialization
/// </summary>
/// <param name="request">RestRequest before serialization</param>
/// <returns>Value Tags</returns>
public virtual ValueTask InterceptBeforeSerialization(RestRequest request) {
return new();
}

/// <summary>
/// Intercepts the request before being sent
/// </summary>
/// <param name="req">HttpRequestMessage before being sent</param>
/// <returns>Value Tags</returns>
public virtual ValueTask InterceptBeforeRequest(HttpRequestMessage req) {
return new();
}

/// <summary>
/// Intercepts the request before being sent
/// </summary>
/// <param name="responseMessage">HttpResponseMessage as received from Server</param>
/// <returns>Value Tags</returns>
public virtual ValueTask InterceptAfterRequest(HttpResponseMessage responseMessage) {
return new();
}

/// <summary>
/// Intercepts the request before deserialization
/// </summary>
/// <param name="response">HttpResponseMessage as received from Server</param>
/// <returns>Value Tags</returns>
public virtual ValueTask InterceptBeforeDeserialize(RestResponse response) {
return new();
}
}
3 changes: 3 additions & 0 deletions src/RestSharp/Options/RestClientOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using System.Text;
using RestSharp.Authenticators;
using RestSharp.Extensions;
using RestSharp.Interceptors;

// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable PropertyCanBeMadeInitOnly.Global
Expand Down Expand Up @@ -64,6 +65,8 @@ public RestClientOptions(string baseUrl) : this(new Uri(Ensure.NotEmptyString(ba
/// </summary>
public IAuthenticator? Authenticator { get; set; }

public List<Interceptor> Interceptors { get; set; } = new();

/// <summary>
/// Passed to <see cref="HttpMessageHandler"/> <code>Credentials</code> property
/// </summary>
Expand Down
70 changes: 50 additions & 20 deletions src/RestSharp/RestClient.Async.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ async Task<HttpResponse> ExecuteRequestAsync(RestRequest request, CancellationTo
throw new ObjectDisposedException(nameof(RestClient));
}

await OnBeforeSerialization(request).ConfigureAwait(false);
request.ValidateParameters();
var authenticator = request.Authenticator ?? Options.Authenticator;

Expand All @@ -98,38 +99,67 @@ async Task<HttpResponse> ExecuteRequestAsync(RestRequest request, CancellationTo

var ct = cts.Token;


HttpResponseMessage? responseMessage;
// Make sure we have a cookie container if not provided in the request
CookieContainer cookieContainer = request.CookieContainer ??= new CookieContainer();

var headers = new RequestHeaders()
.AddHeaders(request.Parameters)
.AddHeaders(DefaultParameters)
.AddAcceptHeader(AcceptedContentTypes)
.AddCookieHeaders(url, cookieContainer)
.AddCookieHeaders(url, Options.CookieContainer);

message.AddHeaders(headers);
if (request.OnBeforeRequest != null) await request.OnBeforeRequest(message).ConfigureAwait(false);
await OnBeforeRequest(message).ConfigureAwait(false);

try {
// Make sure we have a cookie container if not provided in the request
var cookieContainer = request.CookieContainer ??= new CookieContainer();

var headers = new RequestHeaders()
.AddHeaders(request.Parameters)
.AddHeaders(DefaultParameters)
.AddAcceptHeader(AcceptedContentTypes)
.AddCookieHeaders(url, cookieContainer)
.AddCookieHeaders(url, Options.CookieContainer);

message.AddHeaders(headers);

if (request.OnBeforeRequest != null) await request.OnBeforeRequest(message).ConfigureAwait(false);

var responseMessage = await HttpClient.SendAsync(message, request.CompletionOption, ct).ConfigureAwait(false);

responseMessage = await HttpClient.SendAsync(message, request.CompletionOption, ct).ConfigureAwait(false);
// Parse all the cookies from the response and update the cookie jar with cookies
if (responseMessage.Headers.TryGetValues(KnownHeaders.SetCookie, out var cookiesHeader)) {
// ReSharper disable once PossibleMultipleEnumeration
cookieContainer.AddCookies(url, cookiesHeader);
// ReSharper disable once PossibleMultipleEnumeration
Options.CookieContainer?.AddCookies(url, cookiesHeader);
}

if (request.OnAfterRequest != null) await request.OnAfterRequest(responseMessage).ConfigureAwait(false);

return new HttpResponse(responseMessage, url, cookieContainer, null, timeoutCts.Token);
}
catch (Exception ex) {
return new HttpResponse(null, url, null, ex, timeoutCts.Token);
}
if (request.OnAfterRequest != null) await request.OnAfterRequest(responseMessage).ConfigureAwait(false);
await OnAfterRequest(responseMessage).ConfigureAwait(false);
return new HttpResponse(responseMessage, url, cookieContainer, null, timeoutCts.Token);

}

/// <summary>
/// Will be called before the Request becomes Serialized
/// </summary>
/// <param name="request">RestRequest before it will be serialized</param>
async Task OnBeforeSerialization(RestRequest request) {
foreach (var interceptor in Options.Interceptors) {
await interceptor.InterceptBeforeSerialization(request); //.ThrowExceptionIfAvailable();
}
}
/// <summary>
/// Will be called before the Request will be sent
/// </summary>
/// <param name="requestMessage">HttpRequestMessage ready to be sent</param>
async Task OnBeforeRequest(HttpRequestMessage requestMessage) {
foreach (var interceptor in Options.Interceptors) {
await interceptor.InterceptBeforeRequest(requestMessage);
}
}
/// <summary>
/// Will be called after the Response has been received from Server
/// </summary>
/// <param name="responseMessage">HttpResponseMessage as received from server</param>
async Task OnAfterRequest(HttpResponseMessage responseMessage) {
foreach (var interceptor in Options.Interceptors) {
await interceptor.InterceptAfterRequest(responseMessage);
}
}

record HttpResponse(
Expand Down
12 changes: 12 additions & 0 deletions src/RestSharp/RestClient.Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,20 @@ public static async Task<RestResponse<T>> ExecuteAsync<T>(
if (request == null) throw new ArgumentNullException(nameof(request));

var response = await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false);
await OnBeforeDeserialization(response, client.Options).ConfigureAwait(false);
return client.Serializers.Deserialize<T>(request, response, client.Options);
}

/// <summary>
/// Will be called before the Data will be serialized
/// </summary>
/// <param name="raw">RestResponse with Data still in Content</param>
/// <param name="options">RestClient options but readonly</param>
static async Task OnBeforeDeserialization(RestResponse raw, ReadOnlyRestClientOptions options) {
foreach (var interceptor in options.Interceptors) {
await interceptor.InterceptBeforeDeserialize(raw);
}
}

/// <summary>
/// Executes the request synchronously, authenticating if needed
Expand Down
1 change: 1 addition & 0 deletions src/RestSharp/Serializers/RestSerializers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ internal RestResponse<T> Deserialize<T>(RestRequest request, RestResponse raw, R

return response;
}


/// <summary>
/// Deserialize the response content into the specified type
Expand Down
127 changes: 127 additions & 0 deletions test/RestSharp.Tests.Integrated/Interceptor/InterceptorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Copyright (c) .NET Foundation and Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

using Moq;
using RestSharp.Tests.Integrated.Server;

namespace RestSharp.Tests.Integrated.Interceptor;

[Collection(nameof(TestServerCollection))]
public class InterceptorTests {
readonly RestClient _client;

public InterceptorTests(TestServerFixture fixture) => _client = new RestClient(fixture.Server.Url);

[Fact]
public async Task AddInterceptor_ShouldBeUsed() {
//Arrange
var body = new TestRequest("foo", 100);
var request = new RestRequest("post/json").AddJsonBody(body);

var mockInterceptor = new Mock<Interceptors.Interceptor>();
var interceptor = mockInterceptor.Object;
var options = _client.Options;
options.Interceptors.Add(interceptor);
//Act
var response = await _client.ExecutePostAsync<TestResponse>(request);
//Assert
mockInterceptor.Verify(m => m.InterceptBeforeSerialization(It.IsAny<RestRequest>()));
mockInterceptor.Verify(m => m.InterceptBeforeRequest(It.IsAny<HttpRequestMessage>()));
mockInterceptor.Verify(m => m.InterceptAfterRequest(It.IsAny<HttpResponseMessage>()));
mockInterceptor.Verify(m => m.InterceptBeforeDeserialize(It.IsAny<RestResponse>()));
}
[Fact]
public async Task ThrowExceptionIn_InterceptBeforeSerialization_ShouldBeCatchedInTest() {
//Arrange
var body = new TestRequest("foo", 100);
var request = new RestRequest("post/json").AddJsonBody(body);

var mockInterceptor = new Mock<Interceptors.Interceptor>();
mockInterceptor.Setup(m => m.InterceptBeforeSerialization(It.IsAny<RestRequest>())).Throws<Exception>(() => throw new Exception("DummyException"));
var interceptor = mockInterceptor.Object;
var options = _client.Options;
options.Interceptors.Add(interceptor);
//Act
var action = () => _client.ExecutePostAsync<TestResponse>(request);
//Assert
await action.Should().ThrowAsync<Exception>().WithMessage("DummyException");
mockInterceptor.Verify(m => m.InterceptBeforeSerialization(It.IsAny<RestRequest>()));
mockInterceptor.Verify(m => m.InterceptBeforeRequest(It.IsAny<HttpRequestMessage>()),Times.Never);
mockInterceptor.Verify(m => m.InterceptAfterRequest(It.IsAny<HttpResponseMessage>()),Times.Never);
mockInterceptor.Verify(m => m.InterceptBeforeDeserialize(It.IsAny<RestResponse>()),Times.Never);
}
[Fact]
public async Task ThrowExceptionIn_InterceptBeforeRequest_ShouldBeCatchableInTest() {
//Arrange
var body = new TestRequest("foo", 100);
var request = new RestRequest("post/json").AddJsonBody(body);

var mockInterceptor = new Mock<Interceptors.Interceptor>();
mockInterceptor.Setup(m => m.InterceptBeforeRequest(It.IsAny<HttpRequestMessage>())).Throws<Exception>(() => throw new Exception("DummyException"));
var interceptor = mockInterceptor.Object;
var options = _client.Options;
options.Interceptors.Add(interceptor);
//Act
var action = () => _client.ExecutePostAsync<TestResponse>(request);
//Assert
await action.Should().ThrowAsync<Exception>().WithMessage("DummyException");
mockInterceptor.Verify(m => m.InterceptBeforeSerialization(It.IsAny<RestRequest>()));
mockInterceptor.Verify(m => m.InterceptBeforeRequest(It.IsAny<HttpRequestMessage>()));
mockInterceptor.Verify(m => m.InterceptAfterRequest(It.IsAny<HttpResponseMessage>()),Times.Never);
mockInterceptor.Verify(m => m.InterceptBeforeDeserialize(It.IsAny<RestResponse>()),Times.Never);
}
[Fact]
public async Task ThrowExceptionIn_InterceptAfterRequest_ShouldBeCatchableInTest() {
//Arrange
var body = new TestRequest("foo", 100);
var request = new RestRequest("post/json").AddJsonBody(body);

var mockInterceptor = new Mock<Interceptors.Interceptor>();
mockInterceptor.Setup(m => m.InterceptAfterRequest(It.IsAny<HttpResponseMessage>())).Throws<Exception>(() => throw new Exception("DummyException"));
var interceptor = mockInterceptor.Object;
var options = _client.Options;
options.Interceptors.Add(interceptor);
//Act
var action = () => _client.ExecutePostAsync<TestResponse>(request);
//Assert
await action.Should().ThrowAsync<Exception>().WithMessage("DummyException");
mockInterceptor.Verify(m => m.InterceptBeforeSerialization(It.IsAny<RestRequest>()));
mockInterceptor.Verify(m => m.InterceptBeforeRequest(It.IsAny<HttpRequestMessage>()));
mockInterceptor.Verify(m => m.InterceptAfterRequest(It.IsAny<HttpResponseMessage>()));
mockInterceptor.Verify(m => m.InterceptBeforeDeserialize(It.IsAny<RestResponse>()),Times.Never);
}
[Fact]
public async Task ThrowException_InInterceptBeforeDeserialize_ShouldBeCatchableInTest() {
//Arrange
var body = new TestRequest("foo", 100);
var request = new RestRequest("post/json").AddJsonBody(body);

var mockInterceptor = new Mock<Interceptors.Interceptor>();
mockInterceptor.Setup(m => m.InterceptBeforeDeserialize(It.IsAny<RestResponse>())).Throws<Exception>(() => throw new Exception("DummyException"));
var interceptor = mockInterceptor.Object;
var options = _client.Options;
options.Interceptors.Add(interceptor);
//Act
var action = () => _client.PostAsync<TestResponse>(request);
//Assert
await action.Should().ThrowAsync<Exception>().WithMessage("DummyException");
mockInterceptor.Verify(m => m.InterceptBeforeSerialization(It.IsAny<RestRequest>()));
mockInterceptor.Verify(m => m.InterceptBeforeRequest(It.IsAny<HttpRequestMessage>()));
mockInterceptor.Verify(m => m.InterceptAfterRequest(It.IsAny<HttpResponseMessage>()));
mockInterceptor.Verify(m => m.InterceptBeforeDeserialize(It.IsAny<RestResponse>()));
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="HttpTracer" Version="2.1.1" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="6.0.21" />
<PackageReference Include="Polly" Version="7.2.4" />
<PackageReference Include="Xunit.Extensions.Logging" Version="1.1.0" />
Expand Down