【问题标题】:Can I handle case insensitive string in my mock?我可以在我的模拟中处理不区分大小写的字符串吗?
【发布时间】:2016-08-09 09:55:24
【问题描述】:

NUnit 3.4.1,JustMock 2016.2.713.2

我有正在测试的课程:

public class AppManager {
    public string[] GetAppSets() => Registry.LocalMachine
        .OpenSubKey(@"SOFTWARE\Autodesk\AutoCAD", false)
        ?.GetSubKeyNames();
}

另外,我对GetAppSets 方法进行了测试:

[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);
}

它有效。但如果GetAppSets 方法使用“Software\Autodesk\AutoCAD”或“software\autodesk\autocad”字符串而不是“SOFTWARE”,我的测试将失败\Autodesk\AutoCAD":如果字符串大小写发生变化,appSets 变量将为 null(因为我的计算机上不存在该注册表项)。

因此,在这种情况下,或者测试人员需要知道GetAppSets方法的实现(坏的变体),或者来处理不区分大小写的参数 字符串。

是否可以使用第二种变体?

【问题讨论】:

    标签: c# unit-testing testing justmock


    【解决方案1】:

    回答原始问题:

    您可以使用等式断​​言的重载版本。

    Assert.AreEqual(fakeSets, appSets, true);
    

    签名:

    public static void AreEqual(
    string expected,
    string actual,
    bool ignoreCase)
    

    来源:https://msdn.microsoft.com/en-us/library/ms243448.aspx

    更新问题的答案:

    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);
    }
    

    【讨论】:

    • 不,我的问题是其他的。 appSets 将是 null 如果字符串大小写将被更改(因为我的计算机上不存在该注册表项)。我现在将此附加信息添加到我的主题中。
    • 我明白你的意思。正如您的标签中所述,它是一个单元测试,因此允许与其他组件(例如注册表)进行交互。也为 GetAppSets 使用模拟。
    • 我在测试中为我的GetAppSets 使用了一个模拟。我使用 NUnit 和 JustMock 框架。
    • @AndreyBushman 你不能模拟具体的实现。看看stackoverflow.com/a/37194417/5505949
    • 谢谢。另外我对你的回答有意见(关于第三个参数):我在测试中比较了两个字符串数组而不是两个字符串。
    【解决方案2】:

    @Karolis 的回答似乎没有抓住问题的重点。

    正确的解决方案是在排列中使用匹配器以不区分大小写的方式匹配键:

        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);
    

    在上面的mockKey 将与mock 是相同的实例,因为第一个参数上的参数匹配器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-28
      • 1970-01-01
      • 2010-10-10
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多