Reputation: 12486
NUnit 3.4.1, JustMock 2016.2.713.2
I have the class under test:
public class AppManager {
public string[] GetAppSets() => Registry.LocalMachine
.OpenSubKey(@"SOFTWARE\Autodesk\AutoCAD", false)
?.GetSubKeyNames();
}
Also, I have the test for GetAppSets
method:
[Test]
public void GetAppSets_Returns_ValidValue() {
const string subkey = @"SOFTWARE\Autodesk\AutoCAD";
/* The sets of applications which are based on
* AutoCAD 2009-2017. */
string[] fakeSets = new[] { "R17.2", "R18.0",
"R18.1", "R18.2", "R19.0", "R19.1", "R20.0",
"R20.1","R21.0" };
RegistryKey rk = Mock.Create<RegistryKey>();
Mock.Arrange(() => rk.GetSubKeyNames()).Returns(
fakeSets);
Mock.Arrange(() => Registry.LocalMachine.OpenSubKey
(subkey, false)).Returns(rk);
AppManager appMng = new AppManager();
string[] appSets = appMng.GetAppSets();
Assert.AreEqual(fakeSets, appSets);
}
It works. But my test will be failure if GetAppSets
method uses "Software\Autodesk\AutoCAD" or "software\autodesk\autocad" string instead of "SOFTWARE\Autodesk\AutoCAD": the appSets
variable will be null
if string case will be changed (because that registry key doesn't exist on my computer).
So, at this case either tester needs to know theGetAppSets
method implementation (the bad variant), or to handle parameter like the case insensitive string.
Is it possible to use the second variant?
Upvotes: 2
Views: 1147
Reputation: 14473
It seems that the answer by @Karolis misses the point of the question.
The correct solution is to use a matcher in the arrangement to match the key in a case-insensitive manner:
var mock = Mock.Create<RegistryKey>();
Mock.Arrange(() => Registry.LocalMachine.OpenSubKey(
Arg.Matches<string>(s => StringComparer.OrdinalIgnoreCase.Equals(s, @"SOFTWARE\Autodesk\AutoCAD")),
Arg.AnyBool)
).Returns(mock);
var mockKey = Registry.LocalMachine.OpenSubKey(@"software\autodesk\autocad", false);
In the above mockKey
will be the same instance as mock
, because of the argument matcher on the first argument.
Upvotes: 0
Reputation: 1543
Answer to original question:
You can use an overloaded version of equality assertion.
Assert.AreEqual(fakeSets, appSets, true);
Signature:
public static void AreEqual(
string expected,
string actual,
bool ignoreCase)
Source: https://msdn.microsoft.com/en-us/library/ms243448.aspx
Answer to updated question:
for(int i = 0; i < appSets.Length, i++)
{ // If there is mismatch in length Exception will fail the test.
Assert.AreEqual(fakeSets[i], appSets[i], true);
}
Upvotes: 1