Skip to content

Commit d12a087

Browse files
authored
Merge pull request #20 from sliedig/unmock
feat: replaced moq with NSubsitute
2 parents c2430ff + f479752 commit d12a087

File tree

16 files changed

+153
-167
lines changed

16 files changed

+153
-167
lines changed

Unicorn.Contracts/ContractsService.Test/ContractsService.Tests.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
<PackageReference Include="Amazon.Lambda.Core" Version="2.1.0" />
1111
<PackageReference Include="Amazon.Lambda.DynamoDBEvents" Version="2.1.1" />
1212
<PackageReference Include="Amazon.Lambda.TestUtilities" Version="2.0.0" />
13-
<PackageReference Include="AWSSDK.DynamoDBv2" Version="3.7.200.9" />
13+
<PackageReference Include="AWSSDK.DynamoDBv2" Version="3.7.200.17" />
1414
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" />
15-
<PackageReference Include="Moq" Version="4.18.4" />
15+
<PackageReference Include="NSubstitute" Version="5.0.0" />
1616
<PackageReference Include="xunit" Version="2.5.0" />
17-
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
17+
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
1818
<PrivateAssets>all</PrivateAssets>
1919
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2020
</PackageReference>

Unicorn.Contracts/ContractsService.Test/CreateContractFunctionTest.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
using System.Threading.Tasks;
88
using Amazon.DynamoDBv2.DataModel;
99
using Amazon.Lambda.APIGatewayEvents;
10-
using Moq;
10+
using NSubstitute;
1111
using Xunit;
1212
using Xunit.Abstractions;
1313

14+
[assembly: CollectionBehavior(DisableTestParallelization = true)]
15+
1416
namespace Unicorn.Contracts.ContractService.Tests;
1517

1618
[Collection("Sequential")]
@@ -31,10 +33,10 @@ public async Task CreateValidContractPublishesDraftContractStatusChangedEvent()
3133
{
3234
// Arrange
3335
var request = TestHelpers.LoadApiGatewayProxyRequest("./events/create_valid_event.json");
34-
35-
var mockDynamoDbContext = new Mock<IDynamoDBContext>();
3636

37-
var mockPublisher = new Mock<IPublisher>();
37+
var mockDynamoDbContext = Substitute.For<IDynamoDBContext>();
38+
39+
var mockPublisher = Substitute.For<IPublisher>();
3840

3941
var context = TestHelpers.NewLambdaContext();
4042

@@ -45,13 +47,12 @@ public async Task CreateValidContractPublishesDraftContractStatusChangedEvent()
4547
};
4648

4749
var function =
48-
new CreateContractFunction(mockDynamoDbContext.Object, mockPublisher.Object);
50+
new CreateContractFunction(mockDynamoDbContext, mockPublisher);
4951

5052
var response = await function.FunctionHandler(request, context);
51-
52-
mockPublisher.Verify(
53-
client => client.PublishEvent(It.IsAny<Contract>()), Times.Once); //TODO: Verify with contract status = DRAFT
54-
53+
54+
await mockPublisher.Received(1).PublishEvent(Arg.Any<Contract>());
55+
5556
_testOutputHelper.WriteLine("Lambda Response: \n" + response.Body);
5657
_testOutputHelper.WriteLine("Expected Response: \n" + expectedResponse.Body);
5758

Unicorn.Contracts/ContractsService.Test/UpdateContractFunctionTest.cs

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Collections.Immutable;
67
using System.Net;
78
using System.Threading;
89
using System.Threading.Tasks;
910
using Amazon.DynamoDBv2.DataModel;
1011
using Amazon.Lambda.APIGatewayEvents;
11-
using Moq;
12+
using NSubstitute;
1213
using Xunit;
1314
using Xunit.Abstractions;
1415

@@ -22,7 +23,7 @@ public class UpdateContractFunctionTest
2223
public UpdateContractFunctionTest(ITestOutputHelper testOutputHelper)
2324
{
2425
_testOutputHelper = testOutputHelper;
25-
26+
2627
// Set env variable for Powertools Metrics
2728
Environment.SetEnvironmentVariable("POWERTOOLS_METRICS_NAMESPACE", "ContractService");
2829
}
@@ -31,40 +32,36 @@ public UpdateContractFunctionTest(ITestOutputHelper testOutputHelper)
3132
public async Task UpdateContractPublishesApprovedContractStatusChangedEvent()
3233
{
3334
var request = TestHelpers.LoadApiGatewayProxyRequest("./events/update_valid_event.json");
34-
35-
var mockDynamoDbContext = new Mock<IDynamoDBContext>();
36-
var retContract = new Contract()
37-
{
38-
PropertyId = "usa/anytown/main-street/123",
39-
ContractId = Guid.NewGuid(),
40-
Address = new Address()
35+
36+
var mockDynamoDbContext = Substitute.For<IDynamoDBContext>();
37+
38+
mockDynamoDbContext.LoadAsync<Contract>(Arg.Any<string>(), Arg.Any<CancellationToken>())
39+
.Returns(new Contract()
4140
{
42-
City = "anytown",
43-
Number = 123,
44-
Street = "main-street"
45-
}
46-
};
47-
48-
mockDynamoDbContext
49-
.Setup(x => x.LoadAsync<Contract>(It.IsAny<string>(), CancellationToken.None).Result)
50-
.Returns(retContract);
51-
52-
var mockPublisher = new Mock<IPublisher>();
41+
PropertyId = "usa/anytown/main-street/123",
42+
ContractId = Guid.NewGuid(),
43+
Address = new Address()
44+
{
45+
City = "anytown",
46+
Number = 123,
47+
Street = "main-street"
48+
}
49+
});
50+
51+
var mockPublisher = Substitute.For<IPublisher>();
5352

54-
var context = TestHelpers.NewLambdaContext();
53+
var context = TestHelpers.NewLambdaContext();
5554

5655
var expectedResponse = new APIGatewayProxyResponse
5756
{
5857
StatusCode = (int)HttpStatusCode.OK,
5958
Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } }
6059
};
6160

62-
var function = new UpdateContractFunction(mockDynamoDbContext.Object, mockPublisher.Object);
61+
var function = new UpdateContractFunction(mockDynamoDbContext, mockPublisher);
6362
var response = await function.FunctionHandler(request, context);
6463

65-
mockPublisher.Verify(
66-
client => client.PublishEvent(It.IsAny<Contract>()), Times.Once);
67-
//TODO: Verify with contract status = DRAFT
64+
await mockPublisher.Received(1).PublishEvent(Arg.Any<Contract>());
6865

6966
_testOutputHelper.WriteLine("Lambda Response: \n" + response.Body);
7067
_testOutputHelper.WriteLine("Expected Response: \n" + expectedResponse.Body);

Unicorn.Contracts/ContractsService/ContractsService.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
<PackageReference Include="AWS.Lambda.Powertools.Logging" Version="1.1.1" />
1818
<PackageReference Include="AWS.Lambda.Powertools.Metrics" Version="1.3.2" />
1919
<PackageReference Include="AWS.Lambda.Powertools.Tracing" Version="1.1.1" />
20-
<PackageReference Include="AWSSDK.DynamoDBv2" Version="3.7.200.9" />
21-
<PackageReference Include="AWSSDK.EventBridge" Version="3.7.200.10" />
20+
<PackageReference Include="AWSSDK.DynamoDBv2" Version="3.7.200.17" />
21+
<PackageReference Include="AWSSDK.EventBridge" Version="3.7.200.16" />
2222
<PackageReference Include="AWSXRayRecorder.Handlers.AwsSdk" Version="2.12.0" />
2323
</ItemGroup>
2424
</Project>

Unicorn.Contracts/ContractsService/UpdateContractFunction.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ public UpdateContractFunction(IDynamoDBContext dynamoDbContext, IPublisher publi
6363
/// <param name="apigProxyEvent">API Gateway Lambda Proxy Request that triggers the function.</param>
6464
/// <param name="context">The context for the Lambda function.</param>
6565
/// <returns>API Gateway Lambda Proxy Response.</returns>
66-
[Tracing]
66+
[Logging(LogEvent = true)]
6767
[Metrics(CaptureColdStart = true)]
68-
[Logging(LogEvent = true, CorrelationIdPath = CorrelationIdPaths.ApiGatewayRest)]
68+
[Tracing(CaptureMode = TracingCaptureMode.ResponseAndError)]
6969
public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest apigProxyEvent,
7070
ILambdaContext context)
7171
{

Unicorn.Properties/PropertiesService.Tests/PropertiesApprovalSyncFunctionTest.cs

Lines changed: 73 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using Amazon.DynamoDBv2.DataModel;
55
using Amazon.StepFunctions;
66
using Amazon.StepFunctions.Model;
7-
using Moq;
7+
using NSubstitute;
88
using Xunit;
99
using Xunit.Abstractions;
1010

@@ -39,33 +39,31 @@ public void StatusIsDraftSyncShouldNotSendTaskSuccess()
3939
// Setup
4040
var ddbEvent = TestHelpers.LoadDynamoDbEventSource("./events/StreamEvents/contract_status_changed_draft.json");
4141

42-
var retContractStatusItem = new ContractStatusItem
43-
{
44-
PropertyId = "usa/anytown/main-street/999",
45-
ContractId = Guid.NewGuid(),
46-
ContractStatus = "DRAFT",
47-
ContractLastModifiedOn = DateTime.Today,
48-
SfnWaitApprovedTaskToken = null
49-
};
50-
51-
var mockDynamoDbContext = new Mock<IDynamoDBContext>();
52-
53-
mockDynamoDbContext
54-
.Setup(x => x.LoadAsync<ContractStatusItem>(It.IsAny<string>(), CancellationToken.None).Result)
55-
.Returns(retContractStatusItem);
56-
57-
var mockStepFunctionsClient = new Mock<AmazonStepFunctionsClient>();
58-
42+
var mockDynamoDbContext = Substitute.For<IDynamoDBContext>();
43+
44+
mockDynamoDbContext.LoadAsync<ContractStatusItem>(Arg.Any<string>(), Arg.Is(CancellationToken.None))
45+
.Returns(new ContractStatusItem
46+
{
47+
PropertyId = "usa/anytown/main-street/999",
48+
ContractId = Guid.NewGuid(),
49+
ContractStatus = "DRAFT",
50+
ContractLastModifiedOn = DateTime.Today,
51+
SfnWaitApprovedTaskToken = null
52+
});
53+
54+
var mockStepFunctionsClient = Substitute.ForPartsOf<AmazonStepFunctionsClient>();
55+
mockStepFunctionsClient.Received(0)
56+
.SendTaskSuccessAsync(Arg.Any<SendTaskSuccessRequest>(),
57+
Arg.Any<CancellationToken>());
58+
5959
var context = TestHelpers.NewLambdaContext();
6060

6161
var function =
62-
new PropertiesApprovalSyncFunction(mockStepFunctionsClient.Object, mockDynamoDbContext.Object);
62+
new PropertiesApprovalSyncFunction(mockStepFunctionsClient, mockDynamoDbContext);
63+
64+
var handler = function.FunctionHandler(ddbEvent, context);
6365

64-
function.FunctionHandler(ddbEvent, context);
6566

66-
mockStepFunctionsClient.Verify(
67-
client => client.SendTaskSuccessAsync(It.IsAny<SendTaskSuccessRequest>(),
68-
It.IsAny<CancellationToken>()), Times.Never);
6967
}
7068

7169

@@ -75,32 +73,32 @@ public Task StatusIsApprovedNoTokenSyncShouldNotSendTaskSuccess()
7573
var ddbEvent =
7674
TestHelpers.LoadDynamoDbEventSource("./events/StreamEvents/contract_status_changed_approved.json");
7775

78-
var retContractStatusItem = new ContractStatusItem
79-
{
80-
PropertyId = "usa/anytown/main-street/999",
81-
ContractId = Guid.NewGuid(),
82-
ContractStatus = "APPROVED",
83-
ContractLastModifiedOn = DateTime.Today,
84-
SfnWaitApprovedTaskToken = null
85-
};
86-
87-
var mockDynamoDbContext = new Mock<IDynamoDBContext>();
88-
mockDynamoDbContext
89-
.Setup(x => x.LoadAsync<ContractStatusItem>(It.IsAny<string>(), CancellationToken.None).Result)
90-
.Returns(retContractStatusItem);
91-
92-
var mockStepFunctionsClient = new Mock<AmazonStepFunctionsClient>();
93-
76+
var mockDynamoDbContext = Substitute.For<IDynamoDBContext>();
77+
mockDynamoDbContext.LoadAsync<ContractStatusItem>(Arg.Any<string>(), Arg.Any<CancellationToken>())
78+
.Returns(new ContractStatusItem
79+
{
80+
PropertyId = "usa/anytown/main-street/999",
81+
ContractId = Guid.NewGuid(),
82+
ContractStatus = "APPROVED",
83+
ContractLastModifiedOn = DateTime.Today,
84+
SfnWaitApprovedTaskToken = null
85+
});
86+
87+
var mockStepFunctionsClient = Substitute.ForPartsOf<AmazonStepFunctionsClient>();
88+
mockStepFunctionsClient.Received(0).
89+
SendTaskSuccessAsync(Arg.Any<SendTaskSuccessRequest>(),
90+
Arg.Any<CancellationToken>());
91+
9492
var context = TestHelpers.NewLambdaContext();
9593

9694
var function =
97-
new PropertiesApprovalSyncFunction(mockStepFunctionsClient.Object, mockDynamoDbContext.Object);
95+
new PropertiesApprovalSyncFunction(mockStepFunctionsClient, mockDynamoDbContext);
9896

9997
function.FunctionHandler(ddbEvent, context);
10098

101-
mockStepFunctionsClient.Verify(
102-
client => client.SendTaskSuccessAsync(It.IsAny<SendTaskSuccessRequest>(),
103-
It.IsAny<CancellationToken>()), Times.Never);
99+
mockStepFunctionsClient.Received(0).
100+
SendTaskSuccessAsync(Arg.Any<SendTaskSuccessRequest>(),
101+
Arg.Any<CancellationToken>());
104102

105103
return Task.CompletedTask;
106104
}
@@ -113,32 +111,30 @@ public Task StatusIsDraftWithTokenSyncShouldNotSendTaskSuccess()
113111
TestHelpers.LoadDynamoDbEventSource(
114112
"./events/StreamEvents/contract_status_draft_waiting_for_approval.json");
115113

116-
var retContractStatusItem = new ContractStatusItem
117-
{
118-
PropertyId = "usa/anytown/main-street/999",
119-
ContractId = Guid.NewGuid(),
120-
ContractStatus = "DRAFT",
121-
ContractLastModifiedOn = DateTime.Today,
122-
SfnWaitApprovedTaskToken = Token
123-
};
124-
125-
var mockDynamoDbContext = new Mock<IDynamoDBContext>();
126-
mockDynamoDbContext
127-
.Setup(x => x.LoadAsync<ContractStatusItem>(It.IsAny<string>(), CancellationToken.None).Result)
128-
.Returns(retContractStatusItem);
114+
var mockDynamoDbContext = Substitute.For<IDynamoDBContext>();
115+
116+
mockDynamoDbContext.LoadAsync<ContractStatusItem>(Arg.Any<string>(), CancellationToken.None)
117+
.Returns(new ContractStatusItem
118+
{
119+
PropertyId = "usa/anytown/main-street/999",
120+
ContractId = Guid.NewGuid(),
121+
ContractStatus = "DRAFT",
122+
ContractLastModifiedOn = DateTime.Today,
123+
SfnWaitApprovedTaskToken = Token
124+
});
129125

130-
var mockStepFunctionsClient = new Mock<AmazonStepFunctionsClient>();
126+
var mockStepFunctionsClient = Substitute.ForPartsOf<AmazonStepFunctionsClient>();
131127

132128
var context = TestHelpers.NewLambdaContext();
133129

134130
var function =
135-
new PropertiesApprovalSyncFunction(mockStepFunctionsClient.Object, mockDynamoDbContext.Object);
131+
new PropertiesApprovalSyncFunction(mockStepFunctionsClient, mockDynamoDbContext);
136132

137133
var handler = function.FunctionHandler(ddbEvent, context);
138134

139-
mockStepFunctionsClient.Verify(
140-
client => client.SendTaskSuccessAsync(It.IsAny<SendTaskSuccessRequest>(),
141-
It.IsAny<CancellationToken>()), Times.Never);
135+
mockStepFunctionsClient.Received(0).
136+
SendTaskSuccessAsync(Arg.Any<SendTaskSuccessRequest>(),
137+
Arg.Any<CancellationToken>());
142138

143139
return Task.CompletedTask;
144140
}
@@ -151,31 +147,27 @@ public Task StatusIsApprovedWithTokenSyncShouldSendTaskSuccess()
151147
TestHelpers.LoadDynamoDbEventSource(
152148
"./events/StreamEvents/contract_status_changed_approved_waiting_for_approval.json");
153149

154-
var retContractStatusItem = new ContractStatusItem
155-
{
156-
PropertyId = "usa/anytown/main-street/999",
157-
ContractId = Guid.NewGuid(),
158-
ContractStatus = "APPROVED",
159-
ContractLastModifiedOn = DateTime.Today,
160-
SfnWaitApprovedTaskToken = Token
161-
};
162-
163-
var mockStepFunctionsClient = new Mock<AmazonStepFunctionsClient>();
164-
var mockDynamoDbContext = new Mock<IDynamoDBContext>();
165-
mockDynamoDbContext
166-
.Setup(x =>
167-
x.LoadAsync<ContractStatusItem>(It.IsAny<string>(),
168-
CancellationToken.None).Result)
169-
.Returns(retContractStatusItem);
150+
var mockStepFunctionsClient = Substitute.ForPartsOf<AmazonStepFunctionsClient>();
151+
var mockDynamoDbContext = Substitute.For<IDynamoDBContext>();
152+
153+
mockDynamoDbContext.LoadAsync<ContractStatusItem>(Arg.Any<string>(), Arg.Is(CancellationToken.None))
154+
.Returns(new ContractStatusItem
155+
{
156+
PropertyId = "usa/anytown/main-street/999",
157+
ContractId = Guid.NewGuid(),
158+
ContractStatus = "APPROVED",
159+
ContractLastModifiedOn = DateTime.Today,
160+
SfnWaitApprovedTaskToken = Token
161+
});
170162
var context = TestHelpers.NewLambdaContext();
171163

172164
var function =
173-
new PropertiesApprovalSyncFunction(mockStepFunctionsClient.Object, mockDynamoDbContext.Object);
165+
new PropertiesApprovalSyncFunction(mockStepFunctionsClient, mockDynamoDbContext);
174166
var handler = function.FunctionHandler(ddbEvent, context);
175167

176-
mockStepFunctionsClient.Verify(
177-
client => client.SendTaskSuccessAsync(It.IsAny<SendTaskSuccessRequest>(),
178-
It.IsAny<CancellationToken>()), Times.Once);
168+
mockStepFunctionsClient.Received(1).
169+
SendTaskSuccessAsync(Arg.Any<SendTaskSuccessRequest>(),
170+
Arg.Any<CancellationToken>());
179171

180172
return Task.CompletedTask;
181173
}

Unicorn.Properties/PropertiesService.Tests/PropertiesService.Tests.csproj

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@
88
<PackageReference Include="Amazon.Lambda.Core" Version="2.1.0" />
99
<PackageReference Include="Amazon.Lambda.TestUtilities" Version="2.0.0" />
1010
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" />
11-
<PackageReference Include="Moq" Version="4.18.4" />
11+
<PackageReference Include="NSubstitute" Version="5.0.0" />
12+
<PackageReference Include="NSubstitute.Analyzers.CSharp" Version="1.0.16">
13+
<PrivateAssets>all</PrivateAssets>
14+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
15+
</PackageReference>
1216
<PackageReference Include="xunit" Version="2.5.0" />
13-
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
17+
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
1418
<PrivateAssets>all</PrivateAssets>
1519
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1620
</PackageReference>

0 commit comments

Comments
 (0)