I've created an application that uses the MS GitHttpClient class to read commits in an AzureDevOps project. I would like to make a unit test of the logic, so I need to mock the VssConnection and GitHttpClient. Neither of the two classes implements any interface.
I can mock the GitHttpClient and make it return commit refs when calling GitHttpClient.GetCommitsAsync(...)
but when I try to mock VssConnection.GetClient<GitHttpClient>()
I get the following exception
Test method mycli.Tests.Unit.Services.GitServiceTests.TestVssConnectionMock threw exception:
System.NotSupportedException: Unsupported expression: conn => conn.GetClient<GitHttpClient>()
Non-overridable members (here: VssConnection.GetClient) may not be used in setup / verification expressions.
Here is my test class. The first test TestVssConnection
fails with the above exception. The second test TestGitHttpClientMock
passes.
[TestClass]
public class GitServiceTests
{
[TestMethod]
public async Task TestVssConnectionMock()
{
var vssConnectionMock = new Mock<VssConnection>(new Uri("http://fake"), new VssCredentials());
var gitHttpClientMock = new Mock<GitHttpClient>(new Uri("http://fake"), new VssCredentials());
gitHttpClientMock.Setup(client => client.GetCommitsAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<GitQueryCommitsCriteria>(), null, null, null, It.IsAny<CancellationToken>())).Returns(Task.FromResult(new List<GitCommitRef> { new GitCommitRef { Comment = "abc" } }));
vssConnectionMock.Setup(conn => conn.GetClient<GitHttpClient>()).Returns(gitHttpClientMock.Object);
// EXCEPTION THROWN ABOVE ^
var gitHttpClient = vssConnectionMock.Object.GetClient<GitHttpClient>();
var commits = await gitHttpClient.GetCommitsAsync("", "", new GitQueryCommitsCriteria());
Assert.IsTrue(commits.Count == 1);
}
[TestMethod]
public async Task TestGitHttpClientMock()
{
var gitHttpClientMock = new Mock<GitHttpClient>(new Uri("http://fake"), new VssCredentials());
gitHttpClientMock.Setup(client => client.GetCommitsAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<GitQueryCommitsCriteria>(), null, null, null, It.IsAny<CancellationToken>())).Returns(Task.FromResult(new List<GitCommitRef> { new GitCommitRef { Comment = "abc" } }));
var commits = await gitHttpClientMock.Object.GetCommitsAsync("", "", new GitQueryCommitsCriteria());
Assert.IsTrue(commits.Count == 1);
}
}
My question is, how do I mock VssConnection.GetClient<GitHttpClient>()
so it returns my mock of GitHttpClient
?
Is the workaround to make a wrapper of VssConnection? And if so, how is that best done?
I am using .NET 6, MsTest and MoQ.