Skip to content

Commit

Permalink
Replace moq with nsubstitute (#233)
Browse files Browse the repository at this point in the history
* Replace Moq with NSubstitute
* Update several packages

Fixes #232
  • Loading branch information
dnperfors authored Aug 9, 2023
1 parent 5c0223f commit d7024f1
Show file tree
Hide file tree
Showing 26 changed files with 220 additions and 224 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Update Java SDK for SonarQube
uses: actions/setup-java@v1
with:
java-version: '11'
java-version: '17'
- name: Setup .NET versions
uses: actions/setup-dotnet@v1
with:
Expand Down Expand Up @@ -77,7 +77,7 @@ jobs:
with:
dotnet-version: |
6.0.x
7.0.x
7.0.306
- name: Dump .NET info
run: dotnet --info
- name: Restore dependencies
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- `ShouldHaveMadeRequestsTo(this TestableHttpMessageHandler, string, bool)` and `ShouldHaveMadeRequestsTo(this TestableHttpMessageHandler, string, bool, int)` have been removed. CaseInsensitivity is controlled by the `UriPatternMatchingOptions` that can be set on the `TestableHttpMessageHandler`.
- `WithRequestUri(this IHttpRequestMessagesCheck, string, bool)` and `WithRequestUri(this IHttpRequestMessagesCheck, string, bool, int)` have been removed. CaseInsensitivity is controlled by the `UriPatternMatchingOptions` that can be set on the `TestableHttpMessageHandler`.
- `WithQueryString` has been removed, since `ShouldHaveMadeRequestTo` and `WithRequestUri` now properly support querystrings.
- Replaced Moq with NSubstitute in test project because of the SponsorLink dependencies.

## [0.10] - 2022-12-03
### Deprecated
Expand Down
8 changes: 4 additions & 4 deletions test/Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<Project>
<ItemGroup>
<PackageReference Include="Microsoft.TestPlatform.ObjectModel" Version="17.6.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PackageReference Include="Microsoft.TestPlatform.ObjectModel" Version="17.6.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using System.Net.Http;

namespace TestableHttpClient.Tests;

public partial class HttpRequestMessageExtensionsTests
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

using NSubstitute;

namespace TestableHttpClient.Tests.HttpRequestMessagesCheckExtensionsTests;

public static class Args
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Non-substitutable member", "NS1004:Argument matcher used with a non-virtual member of a class.", Justification = "This is a custom matcher.")]
public static ref Func<HttpRequestMessage, bool> AnyPredicate() => ref Arg.Any<Func<HttpRequestMessage, bool>>();
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Moq;
using NSubstitute;

namespace TestableHttpClient.Tests.HttpRequestMessagesCheckExtensionsTests;

Expand Down Expand Up @@ -27,42 +27,42 @@ public void WithContent_WithNumberOfRequests_NullCheck_ThrowsArgumentNullExcepti
[Fact]
public void WithContent_WithoutNumberOfRequests_NullPattern_ThrowsArgumentNullException()
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

var exception = Assert.Throws<ArgumentNullException>(() => sut.Object.WithContent(null!));
var exception = Assert.Throws<ArgumentNullException>(() => sut.WithContent(null!));

Assert.Equal("pattern", exception.ParamName);
sut.Verify(x => x.WithFilter(Its.AnyPredicate(), It.IsAny<int?>(), It.IsAny<string>()), Times.Never());
sut.DidNotReceive().WithFilter(Args.AnyPredicate(), Arg.Any<int?>(), Arg.Any<string>());
}

[Fact]
public void WithContent_WithNumberOfRequests_NullPattern_ThrowsArgumentNullException()
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

var exception = Assert.Throws<ArgumentNullException>(() => sut.Object.WithContent(null!, 1));
var exception = Assert.Throws<ArgumentNullException>(() => sut.WithContent(null!, 1));

Assert.Equal("pattern", exception.ParamName);
sut.Verify(x => x.WithFilter(Its.AnyPredicate(), It.IsAny<int?>(), It.IsAny<string>()), Times.Never());
sut.DidNotReceive().WithFilter(Args.AnyPredicate(), Arg.Any<int?>(), Arg.Any<string>());
}

[Fact]
public void WithContent_WithoutNumberOfRequests_CallsWithCorrectly()
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

sut.Object.WithContent("some content");
sut.WithContent("some content");

sut.Verify(x => x.WithFilter(Its.AnyPredicate(), null, "content 'some content'"));
sut.Received(1).WithFilter(Args.AnyPredicate(), null, "content 'some content'");
}

[Fact]
public void WithContent_WithNumberOfRequests_CallsWithCorrectly()
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

sut.Object.WithContent("some content", 1);
sut.WithContent("some content", 1);

sut.Verify(x => x.WithFilter(Its.AnyPredicate(), (int?)1, "content 'some content'"));
sut.Received().WithFilter(Args.AnyPredicate(), (int?)1, "content 'some content'");
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Moq;
using NSubstitute;

namespace TestableHttpClient.Tests.HttpRequestMessagesCheckExtensionsTests;

Expand Down Expand Up @@ -29,44 +29,44 @@ public void WithContentHeader_WithNumberOfRequests_NullCheck_ThrowsArgumentNullE
[InlineData("")]
public void WithContentHeader_WithoutNumberOfRequests_NullOrEmptyHeaderName_ThrowsArgumentNullException(string headerName)
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

var exception = Assert.Throws<ArgumentNullException>(() => sut.Object.WithContentHeader(headerName));
var exception = Assert.Throws<ArgumentNullException>(() => sut.WithContentHeader(headerName));

Assert.Equal("headerName", exception.ParamName);
sut.Verify(x => x.WithFilter(Its.AnyPredicate(), It.IsAny<int?>(), It.IsAny<string>()), Times.Never());
sut.DidNotReceive().WithFilter(Args.AnyPredicate(), Arg.Any<int?>(), Arg.Any<string>());
}

[Theory]
[InlineData(null)]
[InlineData("")]
public void WithContentHeader_WithNumberOfRequests_NullOrEmptyHeaderName_ThrowsArgumentNullException(string headerName)
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

var exception = Assert.Throws<ArgumentNullException>(() => sut.Object.WithContentHeader(headerName, 1));
var exception = Assert.Throws<ArgumentNullException>(() => sut.WithContentHeader(headerName, 1));

Assert.Equal("headerName", exception.ParamName);
sut.Verify(x => x.WithFilter(Its.AnyPredicate(), It.IsAny<int?>(), It.IsAny<string>()), Times.Never());
sut.DidNotReceive().WithFilter(Args.AnyPredicate(), Arg.Any<int?>(), Arg.Any<string>());
}

[Fact]
public void WithContentHeader_WithoutNumberOfRequests_CallsWithCorrectly()
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

sut.Object.WithContentHeader("Content-Type");
sut.WithContentHeader("Content-Type");

sut.Verify(x => x.WithFilter(Its.AnyPredicate(), null, "content header 'Content-Type'"));
sut.Received().WithFilter(Args.AnyPredicate(), null, "content header 'Content-Type'");
}

[Fact]
public void WithContentHeader_WithNumberOfRequests_CallsWithCorrectly()
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

sut.Object.WithContentHeader("Content-Type", 1);
sut.WithContentHeader("Content-Type", 1);

sut.Verify(x => x.WithFilter(Its.AnyPredicate(), (int?)1, "content header 'Content-Type'"));
sut.Received(1).WithFilter(Args.AnyPredicate(), (int?)1, "content header 'Content-Type'");
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Moq;
using NSubstitute;

namespace TestableHttpClient.Tests.HttpRequestMessagesCheckExtensionsTests;

Expand Down Expand Up @@ -29,70 +29,70 @@ public void WihtContentHeaderNameAndValue_WithNumberOfRequests_NullCheck_ThrowsA
[InlineData("")]
public void WithContentHeaderNameAndValue_WithoutNumberOfRequests_NullOrEmptyHeaderName_ThrowsArgumentNullException(string headerName)
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

var exception = Assert.Throws<ArgumentNullException>(() => sut.Object.WithContentHeader(headerName, "someValue"));
var exception = Assert.Throws<ArgumentNullException>(() => sut.WithContentHeader(headerName, "someValue"));

Assert.Equal("headerName", exception.ParamName);
sut.Verify(x => x.WithFilter(Its.AnyPredicate(), It.IsAny<int?>(), It.IsAny<string>()), Times.Never());
sut.DidNotReceive().WithFilter(Args.AnyPredicate(), Arg.Any<int?>(), Arg.Any<string>());
}

[Theory]
[InlineData(null)]
[InlineData("")]
public void WithContentHeaderNameAndValue_WithNumberOfRequests_NullOrEmptyHeaderName_ThrowsArgumentNullException(string headerName)
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

var exception = Assert.Throws<ArgumentNullException>(() => sut.Object.WithContentHeader(headerName, "someValue", 1));
var exception = Assert.Throws<ArgumentNullException>(() => sut.WithContentHeader(headerName, "someValue", 1));

Assert.Equal("headerName", exception.ParamName);
sut.Verify(x => x.WithFilter(Its.AnyPredicate(), It.IsAny<int?>(), It.IsAny<string>()), Times.Never());
sut.DidNotReceive().WithFilter(Args.AnyPredicate(), Arg.Any<int?>(), Arg.Any<string>());
}

[Theory]
[InlineData(null)]
[InlineData("")]
public void WithContentHeaderNameAndValue_WithoutNumberOfRequests_NullOrEmptyValue_ThrowsArgumentNullException(string headerValue)
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

var exception = Assert.Throws<ArgumentNullException>(() => sut.Object.WithContentHeader("someHeader", headerValue));
var exception = Assert.Throws<ArgumentNullException>(() => sut.WithContentHeader("someHeader", headerValue));

Assert.Equal("headerValue", exception.ParamName);
sut.Verify(x => x.WithFilter(Its.AnyPredicate(), It.IsAny<int?>(), It.IsAny<string>()), Times.Never());
sut.DidNotReceive().WithFilter(Args.AnyPredicate(), Arg.Any<int?>(), Arg.Any<string>());
}

[Theory]
[InlineData(null)]
[InlineData("")]
public void WithContentHeaderNameAndValue_WithNumberOfRequests_NullOrEmptyValue_ThrowsArgumentNullException(string headerValue)
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

var exception = Assert.Throws<ArgumentNullException>(() => sut.Object.WithContentHeader("someHeader", headerValue, 1));
var exception = Assert.Throws<ArgumentNullException>(() => sut.WithContentHeader("someHeader", headerValue, 1));

Assert.Equal("headerValue", exception.ParamName);
sut.Verify(x => x.WithFilter(Its.AnyPredicate(), It.IsAny<int?>(), It.IsAny<string>()), Times.Never());
sut.DidNotReceive().WithFilter(Args.AnyPredicate(), Arg.Any<int?>(), Arg.Any<string>());
}

[Fact]
public void WithContentHeaderNameAndValue_WithoutNumberOfRequests_CallsWithCorrectly()
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

sut.Object.WithContentHeader("someHeader", "someValue");
sut.WithContentHeader("someHeader", "someValue");

sut.Verify(x => x.WithFilter(Its.AnyPredicate(), null, "content header 'someHeader' and value 'someValue'"));
sut.Received(1).WithFilter(Args.AnyPredicate(), null, "content header 'someHeader' and value 'someValue'");
}

[Fact]
public void WithContentHeaderNameAndValue_WithNumberOfRequests_CallsWithCorrectly()
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

sut.Object.WithContentHeader("someHeader", "someValue", 1);
sut.WithContentHeader("someHeader", "someValue", 1);

sut.Verify(x => x.WithFilter(Its.AnyPredicate(), (int?)1, "content header 'someHeader' and value 'someValue'"));
sut.Received(1).WithFilter(Args.AnyPredicate(), (int?)1, "content header 'someHeader' and value 'someValue'");
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Moq;
using NSubstitute;

namespace TestableHttpClient.Tests.HttpRequestMessagesCheckExtensionsTests;

Expand Down Expand Up @@ -27,43 +27,43 @@ public void WithFormUrlEncodedContent_WithNumberOfRequests_NulCheck_ThrowsArgume
[Fact]
public void WithFormUrlEncodedContent_WithoutNumberOfRequests_NullNameValueCollection_ThrowsArgumentNullException()
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

var exception = Assert.Throws<ArgumentNullException>(() => sut.Object.WithFormUrlEncodedContent(null!));
var exception = Assert.Throws<ArgumentNullException>(() => sut.WithFormUrlEncodedContent(null!));

Assert.Equal("nameValueCollection", exception.ParamName);
sut.Verify(x => x.WithFilter(Its.AnyPredicate(), It.IsAny<int?>(), It.IsAny<string>()), Times.Never());
sut.DidNotReceive().WithFilter(Args.AnyPredicate(), Arg.Any<int?>(), Arg.Any<string>());
}

[Fact]
public void WithFormUrlEncodedContent_WithNumberOfRequests_NullNameValueCollection_ThrowsArgumentNullException()
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

var exception = Assert.Throws<ArgumentNullException>(() => sut.Object.WithFormUrlEncodedContent(null!, 1));
var exception = Assert.Throws<ArgumentNullException>(() => sut.WithFormUrlEncodedContent(null!, 1));

Assert.Equal("nameValueCollection", exception.ParamName);
sut.Verify(x => x.WithFilter(Its.AnyPredicate(), It.IsAny<int?>(), It.IsAny<string>()), Times.Never());
sut.DidNotReceive().WithFilter(Args.AnyPredicate(), Arg.Any<int?>(), Arg.Any<string>());
}

[Fact]
public void WithFormUrlEncodedContent_WithoutNumberOfRequests_CallsWithCorrectly()
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

sut.Object.WithFormUrlEncodedContent(new[] { new KeyValuePair<string?, string?>("username", "alice") });
sut.WithFormUrlEncodedContent(new[] { new KeyValuePair<string?, string?>("username", "alice") });

sut.Verify(x => x.WithFilter(Its.AnyPredicate(), null, "form url encoded content 'username=alice'"));
sut.Received(1).WithFilter(Args.AnyPredicate(), null, "form url encoded content 'username=alice'");
}

[Fact]
public void WithFormUrlEncodedContent_WithNumberOfRequests_CallsWithCorrectly()
{
Mock<IHttpRequestMessagesCheck> sut = new();
IHttpRequestMessagesCheck sut = Substitute.For<IHttpRequestMessagesCheck>();

sut.Object.WithFormUrlEncodedContent(new[] { new KeyValuePair<string?, string?>("username", "alice") }, 1);
sut.WithFormUrlEncodedContent(new[] { new KeyValuePair<string?, string?>("username", "alice") }, 1);

sut.Verify(x => x.WithFilter(Its.AnyPredicate(), (int?)1, "form url encoded content 'username=alice'"));
sut.Received(1).WithFilter(Args.AnyPredicate(), (int?)1, "form url encoded content 'username=alice'");
}

[Fact]
Expand Down
Loading

0 comments on commit d7024f1

Please sign in to comment.