Use GitHub Copilot Chat in Visual Studio to solve the .NET Moq drama and migrate to NSubstitute

BEN ABT
medialesson
Published in
3 min readFeb 19, 2024

Use GitHub Copilit Chat in Visual Studio to solve the .NET Moq drama and migrate to NSubstitute

It’s now been a few months since the GDPR-drama and data-harvesting around Moq (Stop using Moq as a guinea pig to get feedback on and develop SponsorLink) happened — and the only conclusion that remains is: please migrate away from Moq, as quickly and efficiently as possible.

Migrations

At the time of the drama, regex scripts and manual migrations were quickly recommended to get away from Moq, which sometimes worked more and sometimes less well. However, the larger the code base, the more complex the migration — and the more investment is required to migrate to NSubstitute, for example.

NSubstitute is also the project that has now taken over from Moq as the most popular mocking framework. Please support that project.

GitHub Copilot Chat

The effort of migrating from Moq to NSubstitute can now be significantly reduced thanks to GitHub Copilot Chat. You no longer need regex scripts or manual adjustments — instead, you can use the GitHub Copilot Chat to automate the migration. Automate at least file-by-file, because that’s all the GitHub Copilot Chat currently supports.

Sample

I have several hundred files in an existing application that I was able to migrate successfully in just a few steps; for example, this test file:

public class AccountActivateControllerTests
{
private readonly Mock<IEventEngineCore> _eventEngineMoq = new();
private readonly Mock<IPortalRouter> _prMock = new();
private readonly Mock<IIdentityContextAccessor> _icMoq = new();
private readonly AccountActivateController _controller;

public AccountActivateControllerTests()
{
_controller = new AccountActivateController(
_eventEngineMoq.Object, _icMoq.Object, _prMock.Object);
}

[Fact]
public void Activate_GET_Without_Passed_ActivationKey()
{
// setup
_icMoq.Setup(x => x.GetUserIdOrThrow()).Returns(new UserId(1));

// arrange
AccountActivateController controller = _controller;

// act
IActionResult activateResult = controller.Activate(key: null);
ViewResult viewResult = Assert.IsAssignableFrom<ViewResult>(activateResult);

// assert
viewResult.ViewName.Should().Be("~/Areas/Account/Views/Account/Activate.cshtml");

// verify
_eventEngineMoq
.Verify(ed =>
ed.Send(It.IsAny<UserAccountTryActivateByKeyCommand>(), CancellationToken.None),
Times.Never);
}

I selected this code in the VS editor and prompted convert it from moq to NSubstitute in the Copilot Chat. A few seconds later, GitHub Copilot replaced all moq snippets with NSubstitute actions:

public class AccountActivateControllerTests
{
private readonly IEventEngineCore _eventEngine = Substitute.For<IEventEngineCore>();
private readonly IPortalRouter _pr = Substitute.For<IPortalRouter>();
private readonly IIdentityContextAccessor _ic = Substitute.For<IIdentityContextAccessor>();
private readonly AccountActivateController _controller;

public AccountActivateControllerTests()
{
_controller = new AccountActivateController(_eventEngine, _ic, _pr);
}

[Fact]
public void Activate_GET_Without_Passed_ActivationKey()
{
// setup
_ic.GetUserIdOrThrow().Returns(new UserId(1));

// arrange
AccountActivateController controller = _controller;

// act
IActionResult activateResult = controller.Activate(key: null);
ViewResult viewResult = Assert.IsAssignableFrom<ViewResult>(activateResult);

// assert
viewResult.ViewName.Should().Be("~/Areas/Account/Views/Account/Activate.cshtml");

// verify
_eventEngine
.DidNotReceive()
.Send(Arg.Any<UserAccountTryActivateByKeyCommand>(), CancellationToken.None);
}

GitHub Copilot is simply brilliant! Goodbye Moq. Hello NSubstitute ♥

Autor

Benjamin Abt

Ben is a passionate developer and software architect and especially focused on .NET, cloud and IoT. In his professional he works on high-scalable platforms for IoT and Industry 4.0 focused on the next generation of connected industry based on Azure and .NET. He runs the largest german-speaking C# forum myCSharp.de, is the founder of the Azure UserGroup Stuttgart, a co-organizer of the AzureSaturday, runs his blog, participates in open source projects, speaks at various conferences and user groups and also has a bit free time. He is a Microsoft MVP since 2015 for .NET and Azure.

Originally published at https://schwabencode.com on February 19, 2024.

--

--