Search code examples
c#unit-testingtestingjustmock

Can I handle case insensitive string in my mock?


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?


Solution

  • 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.