Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚧Refactor moq code to nsubstitute #1044

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
40 changes: 20 additions & 20 deletions Testing/VelaptorTests/Content/TextureFactoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace VelaptorTests.Content;
using System.Drawing;
using Carbonate.OneWay;
using FluentAssertions;
using Moq;
using NSubstitute;
using Velaptor.Content.Factories;
using Velaptor.Factories;
using Velaptor.Graphics;
Expand All @@ -22,22 +22,22 @@ namespace VelaptorTests.Content;
/// </summary>
public class TextureFactoryTests
{
private readonly Mock<IGLInvoker> mockGL;
private readonly Mock<IOpenGLService> mockGLService;
private readonly Mock<IReactableFactory> mockReactableFactory;
private readonly IGLInvoker mockGL;
private readonly IOpenGLService mockGLService;
private readonly IReactableFactory mockReactableFactory;

/// <summary>
/// Initializes a new instance of the <see cref="TextureFactoryTests"/> class.
/// </summary>
public TextureFactoryTests()
{
this.mockGL = new Mock<IGLInvoker>();
this.mockGLService = new Mock<IOpenGLService>();
this.mockGL = Substitute.For<IGLInvoker>();
this.mockGLService = Substitute.For<IOpenGLService>();

var mockDisposeReactable = new Mock<IPushReactable<DisposeTextureData>>();
var mockDisposeReactable = Substitute.For<IPushReactable<DisposeTextureData>>();

this.mockReactableFactory = new Mock<IReactableFactory>();
this.mockReactableFactory.Setup(m => m.CreateDisposeTextureReactable()).Returns(mockDisposeReactable.Object);
this.mockReactableFactory = Substitute.For<IReactableFactory>();
this.mockReactableFactory.CreateDisposeTextureReactable().Returns(mockDisposeReactable);
}

#region Constructor Tests
Expand All @@ -49,8 +49,8 @@ public void Ctor_WithNullGLInvoker_ThrowsException()
{
_ = new TextureFactory(
null,
this.mockGLService.Object,
this.mockReactableFactory.Object);
this.mockGLService,
this.mockReactableFactory);
};

// Assert
Expand All @@ -66,9 +66,9 @@ public void Ctor_WithNullOpenGLService_ThrowsException()
var act = () =>
{
_ = new TextureFactory(
this.mockGL.Object,
this.mockGL,
null,
this.mockReactableFactory.Object);
this.mockReactableFactory);
};

// Assert
Expand All @@ -84,8 +84,8 @@ public void Ctor_WithNullReactableFactoryParam_ThrowsException()
var act = () =>
{
_ = new TextureFactory(
this.mockGL.Object,
this.mockGLService.Object,
this.mockGL,
this.mockGLService,
null);
};

Expand Down Expand Up @@ -164,8 +164,8 @@ public void Create_WhenInvoked_WorksCorrectly()

// Assert
// NOTE: These are only here to prove that the same injected objects are the ones being used.
this.mockGL.Verify(m => m.GenTexture(), Times.Once);
this.mockGLService.Verify(m => m.LabelTexture(It.IsAny<uint>(), It.IsAny<string>()), Times.Once);
this.mockGL.Received(1).GenTexture();
this.mockGLService.Received(1).LabelTexture(Arg.Any<uint>(), Arg.Any<string>());
}
#endregion

Expand All @@ -174,7 +174,7 @@ public void Create_WhenInvoked_WorksCorrectly()
/// </summary>
/// <returns>The instance to test.</returns>
private TextureFactory CreateSystemUnderTest() => new (
this.mockGL.Object,
this.mockGLService.Object,
this.mockReactableFactory.Object);
this.mockGL,
this.mockGLService,
this.mockReactableFactory);
}
120 changes: 64 additions & 56 deletions Testing/VelaptorTests/Content/TextureTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ namespace VelaptorTests.Content;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Carbonate.Core.OneWay;
using Carbonate.OneWay;
using FluentAssertions;
using Moq;
using NSubstitute;
using Velaptor.Content;
using Velaptor.Factories;
using Velaptor.Graphics;
Expand All @@ -28,10 +29,10 @@ public class TextureTests
private const string TextureName = "test-texture";
private const string TexturePath = @"C:\temp\test-texture.png";
private const uint TextureId = 1234;
private readonly Mock<IGLInvoker> mockGL;
private readonly Mock<IOpenGLService> mockGLService;
private readonly Mock<IDisposable> mockDisposeUnsubscriber;
private readonly Mock<IReactableFactory> mockReactableFactory;
private readonly IGLInvoker mockGL;
private readonly IOpenGLService mockGLService;
private readonly IDisposable mockDisposeUnsubscriber;
private readonly IReactableFactory mockReactableFactory;
private readonly ImageData imageData;
private IReceiveSubscription<DisposeTextureData>? disposeReactor;

Expand Down Expand Up @@ -75,34 +76,36 @@ public TextureTests()
}
}

this.mockGL = new Mock<IGLInvoker>();
this.mockGL.Setup(m => m.GenTexture()).Returns(TextureId);
this.mockGL = Substitute.For<IGLInvoker>();
this.mockGL.GenTexture().Returns(TextureId);

this.mockGLService = new Mock<IOpenGLService>();
this.mockDisposeUnsubscriber = new Mock<IDisposable>();
this.mockGLService = Substitute.For<IOpenGLService>();
this.mockDisposeUnsubscriber = Substitute.For<IDisposable>();

var mockDisposeReactable = new Mock<IPushReactable<DisposeTextureData>>();
mockDisposeReactable.Setup(m => m.Subscribe(It.IsAny<IReceiveSubscription<DisposeTextureData>>()))
.Returns(this.mockDisposeUnsubscriber.Object)
.Callback<IReceiveSubscription<DisposeTextureData>>(reactor =>
var mockDisposeReactable = Substitute.For<IPushReactable<DisposeTextureData>>();
mockDisposeReactable.Subscribe(Arg.Any<IReceiveSubscription<DisposeTextureData>>())
.Returns(this.mockDisposeUnsubscriber)
.AndDoes(callInfo =>
{
var reactor = callInfo.Arg<IReceiveSubscription<DisposeTextureData>>();
reactor.Should().NotBeNull("It is required for unit testing.");
this.disposeReactor = reactor;
});

this.mockReactableFactory = new Mock<IReactableFactory>();
this.mockReactableFactory.Setup(m => m.CreateDisposeTextureReactable()).Returns(mockDisposeReactable.Object);
this.mockReactableFactory = Substitute.For<IReactableFactory>();
this.mockReactableFactory.CreateDisposeTextureReactable().Returns(mockDisposeReactable);
}

#region Constructor Tests

[Fact]
public void InternalCtor_WithNullGLParam_ThrowsException()
{
// Arrange & Act
var act = () => new Texture(
null,
this.mockGLService.Object,
this.mockReactableFactory.Object,
this.mockGLService,
this.mockReactableFactory,
TextureName,
TexturePath,
this.imageData);
Expand All @@ -117,9 +120,9 @@ public void InternalCtor_WithNullOpenGLServiceParam_ThrowsException()
{
// Arrange & Act
var act = () => new Texture(
this.mockGL.Object,
this.mockGL,
null,
this.mockReactableFactory.Object,
this.mockReactableFactory,
TextureName,
TexturePath,
this.imageData);
Expand All @@ -134,8 +137,8 @@ public void InternalCtor_WithNullReactableFactoryParam_ThrowsException()
{
// Arrange & Act
var act = () => new Texture(
this.mockGL.Object,
this.mockGLService.Object,
this.mockGL,
this.mockGLService,
null,
TextureName,
TexturePath,
Expand All @@ -151,9 +154,9 @@ public void InternalCtor_WithNullName_ThrowsException()
{
// Arrange & Act
var act = () => new Texture(
this.mockGL.Object,
this.mockGLService.Object,
this.mockReactableFactory.Object,
this.mockGL,
this.mockGLService,
this.mockReactableFactory,
null,
TexturePath,
this.imageData);
Expand All @@ -168,9 +171,9 @@ public void InternalCtor_WithEmptyName_ThrowsException()
{
// Arrange & Act
var act = () => new Texture(
this.mockGL.Object,
this.mockGLService.Object,
this.mockReactableFactory.Object,
this.mockGL,
this.mockGLService,
this.mockReactableFactory,
string.Empty,
TexturePath,
this.imageData);
Expand All @@ -185,9 +188,9 @@ public void InternalCtor_WithNullFilePath_ThrowsException()
{
// Act & Assert
var act = () => new Texture(
this.mockGL.Object,
this.mockGLService.Object,
this.mockReactableFactory.Object,
this.mockGL,
this.mockGLService,
this.mockReactableFactory,
TextureName,
null,
this.imageData);
Expand All @@ -202,9 +205,9 @@ public void InternalCtor_WithEmptyFilePath_ThrowsException()
{
// Act & Assert
var act = () => new Texture(
this.mockGL.Object,
this.mockGLService.Object,
this.mockReactableFactory.Object,
this.mockGL,
this.mockGLService,
this.mockReactableFactory,
TextureName,
string.Empty,
this.imageData);
Expand Down Expand Up @@ -250,39 +253,38 @@ public void InternalCtor_WhenInvoked_UploadsTextureDataToGpu()

// Act
_ = new Texture(
this.mockGL.Object,
this.mockGLService.Object,
this.mockReactableFactory.Object,
this.mockGL,
this.mockGLService,
this.mockReactableFactory,
"test-texture.png",
@"C:\temp\test-texture.png",
this.imageData);

// Assert
this.mockGLService.Verify(m => m.LabelTexture(TextureId, "test-texture.png"),
Times.Once());
this.mockGL.Verify(m => m.TexParameter(
this.mockGLService.Received(1).LabelTexture(TextureId, "test-texture.png");
this.mockGL.Received(1).TexParameter(
GLTextureTarget.Texture2D,
GLTextureParameterName.TextureMinFilter,
GLTextureMinFilter.Linear), Times.Once());
GLTextureMinFilter.Linear);

this.mockGL.Verify(m => m.TexParameter(
this.mockGL.Received(1).TexParameter(
GLTextureTarget.Texture2D,
GLTextureParameterName.TextureMagFilter,
GLTextureMagFilter.Linear), Times.Once());
GLTextureMagFilter.Linear);

this.mockGL.Verify(m => m.TexParameter(
this.mockGL.Received(1).TexParameter(
GLTextureTarget.Texture2D,
GLTextureParameterName.TextureWrapS,
GLTextureWrapMode.ClampToEdge), Times.Once());
GLTextureWrapMode.ClampToEdge);

this.mockGL.Verify(m => m.TexParameter(
this.mockGL.Received(1).TexParameter(
GLTextureTarget.Texture2D,
GLTextureParameterName.TextureWrapT,
GLTextureWrapMode.ClampToEdge), Times.Once());
GLTextureWrapMode.ClampToEdge);

var expectedPixelArray = expectedPixelData.ToArray();

this.mockGL.Verify(m => m.TexImage2D<byte>(
this.mockGL.Received(1).TexImage2D<byte>(
GLTextureTarget.Texture2D,
0,
GLInternalFormat.Rgba,
Expand All @@ -291,14 +293,16 @@ public void InternalCtor_WhenInvoked_UploadsTextureDataToGpu()
0,
GLPixelFormat.Rgba,
GLPixelType.UnsignedByte,
expectedPixelArray), Times.Once());
Arg.Is<byte[]>(actualPixelArray => actualPixelArray.SequenceEqual(expectedPixelArray)));
CalvinWilkinson marked this conversation as resolved.
Show resolved Hide resolved

this.mockGLService.Verify(m => m.BindTexture2D(TextureId), Times.Once);
this.mockGLService.Verify(m => m.UnbindTexture2D(), Times.Once);
this.mockGLService.Received(1).BindTexture2D(TextureId);
this.mockGLService.Received(1).UnbindTexture2D();
}

#endregion

#region Prop Tests

[Fact]
public void Id_WhenCreatingTexture_ReturnsCorrectResult()
{
Expand Down Expand Up @@ -363,9 +367,11 @@ public void Height_WhenCreatingTexture_ReturnsCorrectResult()
// Assert
actual.Should().Be(3u);
}

#endregion

#region Method Tests

[Fact]
public void ReactableNotifications_WithDifferentTextureID_DoesNotDisposeOfTexture()
{
Expand All @@ -378,8 +384,8 @@ public void ReactableNotifications_WithDifferentTextureID_DoesNotDisposeOfTextur
this.disposeReactor?.OnReceive(disposeTextureData);

// Assert
this.mockGL.Verify(m => m.DeleteTexture(It.IsAny<uint>()), Times.Never);
this.mockDisposeUnsubscriber.Verify(m => m.Dispose(), Times.Never);
this.mockGL.DidNotReceive().DeleteTexture(Arg.Any<uint>());
this.mockDisposeUnsubscriber.DidNotReceive().Dispose();
}

[Fact]
Expand All @@ -394,8 +400,10 @@ public void ReactableNotifications_WhenPushingDisposeTextureNotification_Dispose
this.disposeReactor?.OnReceive(disposeTextureData);

// Assert
this.mockGL.Verify(m => m.DeleteTexture(TextureId), Times.Once());
// this.mockGL.Verify(m => m.DeleteTexture(TextureId), Times.Once());
this.mockGL.Received(1).DeleteTexture(TextureId);
}

#endregion

/// <summary>
Expand All @@ -404,9 +412,9 @@ public void ReactableNotifications_WhenPushingDisposeTextureNotification_Dispose
/// <returns>The texture instance to test.</returns>
private Texture CreateSystemUnderTest(bool useEmptyData = false)
=> new (
this.mockGL.Object,
this.mockGLService.Object,
this.mockReactableFactory.Object,
this.mockGL,
this.mockGLService,
this.mockReactableFactory,
TextureName,
TexturePath,
useEmptyData ? default : this.imageData);
Expand Down
Loading
Loading