I have an issue that only occurs in my Azure pipeline when running unit tests. The unit tests fail when the methods in the test use the field rankGeneratorinstead of a local variable of the same field. The class examples are written below.
This first code block has rankGenerator as a field, and the pipeline fails with the error message: NSubstitute.Exceptions.RedundantArgumentMatcherException : Some argument specifications (e.g. Arg.Is, Arg.Any) were left over after the last call.
However, if rankGenerator is first declared as a local variable, then the pipeline doesn't fail. Does anyone have an explanation for this behavior?
Failing test example:
public class RiskTests
{
private readonly IRankGenerator rankGenerator = Substitute.For<IRankGenerator>();
private const string OriginalRisk = "Danger danger";
private const string OriginalRank = "Rank 1";
private Risk sut;
public RiskTests()
{
sut = Risk.Create(CreateTestActivity(), OriginalRisk, OriginalRank);
rankGenerator(
Arg.Is<string>(x => x == null || !string.IsNullOrEmpty(x)),
Arg.Is<string>(x => x == null || !string.IsNullOrEmpty(x)))
.GenerateRank().ReturnsForAnyArgs(_ => "000001");
}
[Fact]
public void Should_Add_Mitigation()
{
sut.AddMitigation("Do this to be safe", rankGenerator);
sut.Mitigations.ShouldNotBeEmpty();
sut.Mitigations.Count.ShouldBe(1);
sut.AddMitigation("And this is important", rankGenerator);
sut.Mitigations.Count.ShouldBe(2);
}
}
Passed test example:
public class RiskTests
{
private readonly IRankGenerator rankGenerator = Substitute.For<IRankGenerator>();
private const string OriginalRisk = "Danger danger";
private const string OriginalRank = "Rank 1";
private Risk sut;
public RiskTests()
{
sut = Risk.Create(CreateTestActivity(), OriginalRisk, OriginalRank);
rankGenerator(
Arg.Is<string>(x => x == null || !string.IsNullOrEmpty(x)),
Arg.Is<string>(x => x == null || !string.IsNullOrEmpty(x)))
.GenerateRank().ReturnsForAnyArgs(_ => "000001");
}
[Fact]
public void Should_Add_Mitigation()
{
var localRankGenerator = rankGenerator;
sut.AddMitigation("Do this to be safe", localRankGenerator);
sut.Mitigations.ShouldNotBeEmpty();
sut.Mitigations.Count.ShouldBe(1);
sut.AddMitigation("And this is important", localRankGenerator);
sut.Mitigations.Count.ShouldBe(2);
}
}
Pipeline definition
- task: DotNetCoreCLI@2
inputs:
command: 'test'
projects: '**/RigPlan.sln'
arguments: '--filter CI!=false'
testRunTitle: 'Run .Net Tests'