I would like to mock AuthenticateAsClientAsync
method in the SslStream
class. I also want to mock the different security cases used by the SslStream for example: IsAuthenticated
, IsEncrypted
and IsSigned
. Mocking seems possible, because the method and the properties are virtual or override.
internal bool AuthenticateSSLStream(SslStream sslStream)
{
string certName = myCertificate.GetNameInfo(X509NameType.SimpleName, false);
bool isAuthenticationCompleted = sslStream.AuthenticateAsClientAsync(certName,
new X509Certificate2Collection(myCertificate), SslProtocols.Tls11 | SslProtocols.Tls12, true).Wait(10000);
if (!isAuthenticationCompleted || !sslStream.IsAuthenticated || !sslStream.IsEncrypted || !sslStream.IsSigned)
{
throw new AuthenticationException("Authentication is not succeeded!");
}
return isAuthenticationCompleted;
}
I have created a method and pass a SslStream in order to mock it. A X509Certificate2
certificate was passed through the constructor and stored in the variable name myCertificate
.
How can I coverage all cases of the condition? How to reach the authentication exception using moq?
It is possible to mock with the Moq framework. The SslStream
constructor accepts a Stream
for sending and receiving data.
Step one is to create a streamMock.
Secondly, create a sslStreamMock and passed the mocked Stream object instance to the sslStreamMock.
Next, setup the specific method and property.
private Mock<SslStream> CreateSslStreamMock(Task task, bool isAuthenticated, bool isEncrypted, bool isSigned)
{
Mock<Stream> streamMock = new Mock<Stream>();
streamMock.SetupGet(s => s.CanRead).Returns(true);
streamMock.SetupGet(s => s.CanWrite).Returns(true);
Mock<SslStream> sslStreamMock = new Mock<SslStream>(streamMock.Object);
sslStreamMock.Setup(ss => ss.AuthenticateAsClientAsync(
It.IsAny<string>(),
It.IsAny<X509Certificate2Collection>(),
It.IsAny<SslProtocols>(),
It.IsAny<bool>())).Returns(task);
sslStreamMock.SetupGet(s => s.IsAuthenticated).Returns(isAuthenticated);
sslStreamMock.SetupGet(s => s.IsEncrypted).Returns(isEncrypted);
sslStreamMock.SetupGet(s => s.IsSigned).Returns(isSigned);
return sslStreamMock;
}
It is important to streamMock is readable and writable, otherwise SslStream
constructor will throw ArgumentException, hence unable to create the mock object instance.