Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
06b05f6
initial commit
alexwolfmsft Jul 5, 2023
3815632
Apply suggestions from code review
alexwolfmsft Jul 5, 2023
8b012a3
pr changes
alexwolfmsft Jul 5, 2023
aa29e05
Merge
alexwolfmsft Jul 5, 2023
0a4f450
updates
alexwolfmsft Jul 6, 2023
092d704
fix warnings
alexwolfmsft Jul 6, 2023
952df14
link fixes
alexwolfmsft Jul 6, 2023
d6d3fad
verbiage
alexwolfmsft Jul 6, 2023
dba84f2
added toc
alexwolfmsft Jul 6, 2023
c568045
fix typo
alexwolfmsft Jul 6, 2023
7020570
tweaks
alexwolfmsft Jul 6, 2023
6f43656
fixed linter
alexwolfmsft Jul 6, 2023
2d35fee
updated code samples
alexwolfmsft Jul 6, 2023
e45aaf7
fix typo
alexwolfmsft Jul 7, 2023
ff77752
Update docs/azure/sdk/unit-testing-mocking.md
IEvangelist Jul 7, 2023
b8945c8
Update docs/azure/sdk/unit-testing-mocking.md
IEvangelist Jul 7, 2023
dbfa1e1
Apply suggestions from code review
alexwolfmsft Jul 11, 2023
635489c
Apply suggestions from code review
alexwolfmsft Jul 11, 2023
8832e4d
toc
alexwolfmsft Jul 12, 2023
647037e
Apply suggestions from code review
alexwolfmsft Jul 12, 2023
f92fe66
Apply suggestions from code review
alexwolfmsft Jul 12, 2023
ac29686
Merge branch 'sdk-mocking' of https://github.com/alexwolfmsft/docs in…
alexwolfmsft Jul 12, 2023
cd2f620
Apply suggestions from code review
alexwolfmsft Jul 18, 2023
728a9e9
tabs
alexwolfmsft Jul 18, 2023
9a52fd9
test
alexwolfmsft Jul 18, 2023
879b9d4
snippets test
alexwolfmsft Jul 18, 2023
bb24d01
fixed references
alexwolfmsft Jul 18, 2023
d0626f7
test refactoring
alexwolfmsft Jul 18, 2023
91c794f
fixed code examples
alexwolfmsft Jul 18, 2023
fab1033
refactor
alexwolfmsft Jul 18, 2023
1887cd8
Apply suggestions from code review
alexwolfmsft Jul 19, 2023
e0f62fc
added NSubstitute
alexwolfmsft Jul 19, 2023
7e31736
added nsubstitute tabs
alexwolfmsft Jul 19, 2023
70c3733
Merge branch 'sdk-mocking' of https://github.com/alexwolfmsft/docs in…
alexwolfmsft Jul 19, 2023
6ae919c
renaming
alexwolfmsft Jul 19, 2023
65736c5
removed unnecessary project
alexwolfmsft Jul 19, 2023
ab64050
fixed code sample
alexwolfmsft Jul 19, 2023
4c92a65
updated code samples
alexwolfmsft Jul 19, 2023
f4729fc
Apply suggestions from code review
alexwolfmsft Jul 19, 2023
38470d1
updated snippets
alexwolfmsft Jul 19, 2023
8934a67
Merge branch 'sdk-mocking' of https://github.com/alexwolfmsft/docs in…
alexwolfmsft Jul 19, 2023
0677c5b
Update docs/azure/sdk/unit-testing-mocking.md
alexwolfmsft Jul 19, 2023
bd58529
fixed return
alexwolfmsft Jul 19, 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
2 changes: 2 additions & 0 deletions docs/azure/TOC.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
href: ./sdk/logging.md
- name: Pagination
href: ./sdk/pagination.md
- name: Unit testing and mocking
href: ./sdk/unit-testing-mocking.md
- name: Configure a proxy server
href: ./sdk/azure-sdk-configure-proxy.md
- name: Packages list
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Azure.Security.KeyVault.Secrets;

public class AboutToExpireSecretFinder
{
private readonly TimeSpan _threshold;
private readonly SecretClient _client;

public AboutToExpireSecretFinder(TimeSpan threshold, SecretClient client)
{
_threshold = threshold;
_client = client;
}

public async Task<string[]> GetAboutToExpireSecretsAsync()
{
List<string> secretsAboutToExpire = new();

await foreach (var secret in _client.GetPropertiesOfSecretsAsync())
{
if (secret.ExpiresOn.HasValue &&
secret.ExpiresOn.Value - DateTimeOffset.Now <= _threshold)
{
secretsAboutToExpire.Add(secret.Name);
}
}

return secretsAboutToExpire.ToArray();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using Azure;
using Azure.Security.KeyVault.Secrets;
using Moq;

namespace UnitTestingSampleApp.Moq;

public class AboutToExpireSecretFinderTests_Moq
{
[Fact]
public async Task DoesNotReturnNonExpiringSecrets()
{
// Arrange
// Create a page of enumeration results
Page<SecretProperties> page = Page<SecretProperties>.FromValues(new[]
{
new SecretProperties("secret1") { ExpiresOn = null },
new SecretProperties("secret2") { ExpiresOn = null }
}, null, Mock.Of<Response>());

// Create a pageable that consists of a single page
AsyncPageable<SecretProperties> pageable =
AsyncPageable<SecretProperties>.FromPages(new[] { page });

// Setup a client mock object to return the pageable
var clientMock = new Mock<SecretClient>();
clientMock.Setup(c => c.GetPropertiesOfSecretsAsync(It.IsAny<CancellationToken>()))
.Returns(pageable);

// Create an instance of a class to test passing in the mock client
var finder = new AboutToExpireSecretFinder(TimeSpan.FromDays(2), clientMock.Object);

// Act
string[] soonToExpire = await finder.GetAboutToExpireSecretsAsync();

// Assert
Assert.Empty(soonToExpire);
}

[Fact]
public async Task ReturnsSecretsThatExpireSoon()
{
// Arrange

// Create a page of enumeration results
DateTimeOffset now = DateTimeOffset.Now;
Page<SecretProperties> page = Page<SecretProperties>.FromValues(new[]
{
new SecretProperties("secret1") { ExpiresOn = now.AddDays(1) },
new SecretProperties("secret2") { ExpiresOn = now.AddDays(2) },
new SecretProperties("secret3") { ExpiresOn = now.AddDays(3) }
}, null, Mock.Of<Response>());

// Create a pageable that consists of a single page
AsyncPageable<SecretProperties> pageable =
AsyncPageable<SecretProperties>.FromPages(new[] { page });

// Setup a client mock object to return the pageable
var clientMock = new Mock<SecretClient>();
clientMock.Setup(c => c.GetPropertiesOfSecretsAsync(It.IsAny<CancellationToken>()))
.Returns(pageable);

// Create an instance of a class to test passing in the mock client
var finder = new AboutToExpireSecretFinder(TimeSpan.FromDays(2), clientMock.Object);

// Act
string[] soonToExpire = await finder.GetAboutToExpireSecretsAsync();

// Assert
Assert.Equal(new[] { "secret1", "secret2" }, soonToExpire);
}
}
100 changes: 100 additions & 0 deletions docs/azure/sdk/snippets/unit-testing/Moq/TestSnippets_Moq.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using Azure.Security.KeyVault.Secrets;
using Azure;
using Moq;

namespace UnitTestingSampleApp.Moq;

public class TestSnippets_Moq
{
public void ServiceClientSnippets()
{
// <MockSecretClient>
KeyVaultSecret keyVaultSecret = SecretModelFactory.KeyVaultSecret(
new SecretProperties("secret"), "secretValue");

Mock<SecretClient> clientMock = new Mock<SecretClient>();
clientMock.Setup(c => c.GetSecret(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<CancellationToken>())
)
.Returns(Response.FromValue(keyVaultSecret, Mock.Of<Response>()));

clientMock.Setup(c => c.GetSecretAsync(
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<CancellationToken>())
)
.ReturnsAsync(Response.FromValue(keyVaultSecret, Mock.Of<Response>()));

SecretClient secretClient = clientMock.Object;
// </MockSecretClient>
}

public void ResponseTypeSnippets()
{
// <MockResponse>
Mock<Response> responseMock = new Mock<Response>();
responseMock.SetupGet(r => r.Status).Returns(200);

Response response = responseMock.Object;
// </MockResponse>
}

public void ResponseTypeTSnippets()
{
// <MockResponseT>
KeyVaultSecret keyVaultSecret = SecretModelFactory.KeyVaultSecret(
new SecretProperties("secret"), "secretValue");
Response<KeyVaultSecret> response = Response.FromValue(keyVaultSecret, Mock.Of<Response>());
// </MockResponseT>
}

public void PaggingSnippets()
{
// <SingleResponsePage>
Page<SecretProperties> responsePage = Page<SecretProperties>.FromValues(
new[] {
new SecretProperties("secret1"),
new SecretProperties("secret2")
},
continuationToken: null,
Mock.Of<Response>());
// </SingleResponsePage>

// <MultipleResponsePage>
Page<SecretProperties> page1 = Page<SecretProperties>.FromValues(
new[]
{
new SecretProperties("secret1"),
new SecretProperties("secret2")
},
"continuationToken",
Mock.Of<Response>());

Page<SecretProperties> page2 = Page<SecretProperties>.FromValues(
new[]
{
new SecretProperties("secret3"),
new SecretProperties("secret4")
},
"continuationToken2",
Mock.Of<Response>());

Page<SecretProperties> lastPage = Page<SecretProperties>.FromValues(
new[]
{
new SecretProperties("secret5"),
new SecretProperties("secret6")
},
continuationToken: null,
Mock.Of<Response>());

Pageable<SecretProperties> pageable = Pageable<SecretProperties>
.FromPages(new[] { page1, page2, lastPage });

AsyncPageable<SecretProperties> asyncPageable = AsyncPageable<SecretProperties>
.FromPages(new[] { page1, page2, lastPage });
// </MultipleResponsePage>
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using Azure;
using Azure.Security.KeyVault.Secrets;
using NSubstitute;

namespace UnitTestingSampleApp.NSubstitute;

public class AboutToExpireSecretFinderTests_NSubstitute
{
[Fact]
public async Task DoesNotReturnNonExpiringSecrets()
{
// Arrange
// Create a page of enumeration results
Page<SecretProperties> page = Page<SecretProperties>.FromValues(new[]
{
new SecretProperties("secret1") { ExpiresOn = null },
new SecretProperties("secret2") { ExpiresOn = null }
}, null, Substitute.For<Response>());

// Create a pageable that consists of a single page
AsyncPageable<SecretProperties> pageable =
AsyncPageable<SecretProperties>.FromPages(new[] { page });

// Setup a client mock object to return the pageable
SecretClient clientMock = Substitute.For<SecretClient>();
clientMock.GetPropertiesOfSecretsAsync(Arg.Any<CancellationToken>())
.Returns(pageable);

// Create an instance of a class to test passing in the mock client
var finder = new AboutToExpireSecretFinder(TimeSpan.FromDays(2), clientMock);

// Act
var soonToExpire = await finder.GetAboutToExpireSecretsAsync();

// Assert
Assert.Empty(soonToExpire);
}

[Fact]
public async Task ReturnsSecretsThatExpireSoon()
{
// Arrange

// Create a page of enumeration results
DateTimeOffset now = DateTimeOffset.Now;
Page<SecretProperties> page = Page<SecretProperties>.FromValues(new[]
{
new SecretProperties("secret1") { ExpiresOn = now.AddDays(1) },
new SecretProperties("secret2") { ExpiresOn = now.AddDays(2) },
new SecretProperties("secret3") { ExpiresOn = now.AddDays(3) }
}, null,Substitute.For<Response>());

// Create a pageable that consists of a single page
AsyncPageable<SecretProperties> pageable =
AsyncPageable<SecretProperties>.FromPages(new[] { page });

// Setup a client mock object to return the pageable
SecretClient clientMock = Substitute.For<SecretClient>();
clientMock.GetPropertiesOfSecretsAsync(Arg.Any<CancellationToken>())
.Returns(pageable);

// Create an instance of a class to test passing in the mock client
var finder = new AboutToExpireSecretFinder(TimeSpan.FromDays(2), clientMock);

// Act
var soonToExpire = await finder.GetAboutToExpireSecretsAsync();

// Assert
Assert.Equal(new[] { "secret1", "secret2" }, soonToExpire);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
using Azure.Security.KeyVault.Secrets;
using Azure;
using NSubstitute;

namespace UnitTestingSampleApp.NSubstitute;

public class TestSnippets_NSubstitute
{
public void ServiceClientSnippets()
{
// <MockSecretClient>
KeyVaultSecret keyVaultSecret = SecretModelFactory.KeyVaultSecret(
new SecretProperties("secret"), "secretValue");

SecretClient clientMock = Substitute.For<SecretClient>();
clientMock.GetSecret(
Arg.Any<string>(),
Arg.Any<string>(),
Arg.Any<CancellationToken>()
)
.Returns(Response.FromValue(keyVaultSecret, Substitute.For<Response>()));

clientMock.GetSecretAsync(
Arg.Any<string>(),
Arg.Any<string>(),
Arg.Any<CancellationToken>()
)
.Returns(Response.FromValue(keyVaultSecret, Substitute.For<Response>()));

SecretClient secretClient = clientMock;
// </MockSecretClient>
}

public void ResponseTypeSnippets()
{
// <MockResponse>
Response responseMock = Substitute.For<Response>();
responseMock.Status.Returns(200);

Response response = responseMock;
// </MockResponse>
}

public void ResponseTypeTSnippets()
{
// <MockResponseT>
KeyVaultSecret keyVaultSecret = SecretModelFactory.KeyVaultSecret(
new SecretProperties("secret"), "secretValue");
Response<KeyVaultSecret> response = Response.FromValue(keyVaultSecret, Substitute.For<Response>());
// </MockResponseT>
}


public void PaggingSnippets()
{
// <SingleResponsePage>
Page<SecretProperties> responsePage = Page<SecretProperties>.FromValues(
new[] {
new SecretProperties("secret1"),
new SecretProperties("secret2")
},
continuationToken: null,
Substitute.For<Response>());
// </SingleResponsePage>

// <MultipleResponsePage>
Page<SecretProperties> page1 = Page<SecretProperties>.FromValues(
new[]
{
new SecretProperties("secret1"),
new SecretProperties("secret2")
},
"continuationToken",
Substitute.For<Response>());

Page<SecretProperties> page2 = Page<SecretProperties>.FromValues(
new[]
{
new SecretProperties("secret3"),
new SecretProperties("secret4")
},
"continuationToken2",
Substitute.For<Response>());

Page<SecretProperties> lastPage = Page<SecretProperties>.FromValues(
new[]
{
new SecretProperties("secret5"),
new SecretProperties("secret6")
},
continuationToken: null,
Substitute.For<Response>());

Pageable<SecretProperties> pageable = Pageable<SecretProperties>
.FromPages(new[] { page1, page2, lastPage });

AsyncPageable<SecretProperties> asyncPageable = AsyncPageable<SecretProperties>
.FromPages(new[] { page1, page2, lastPage });
// </MultipleResponsePage>
}

}
Loading