使用 XUnit 测试动态扩展

Testing dynamic expando with XUnit

所以我正在尝试从注入的对话框中测试一个方法 API 正在被调用(使用 CaliburnMicro MVVM 框架)。

方法

public bool? ShowDialog(Screen dialog)
{
    dynamic settings = new ExpandoObject();
    settings.WindowStartupLocation = WindowStartupLocation.CenterOwner;
    settings.ResizeMode = ResizeMode.NoResize;
    return _dialogAPI.ShowDialog(dialog, null, settings);
}

这就是我尝试测试它的方式:

测试

[Fact]
public void DialogServiceCallAPIToShowDialog()
{
    var dialogAPI = new Mock<IWindowManager>();
    dialogAPI.Setup(x => x.ShowDialog(It.IsAny<Screen>(), null, It.IsAny<Dictionary<string, object>>())).Returns(() => true);

    var instance = new DialogService(dialogAPI.Object);
    instance.ShowDialog(It.IsAny<Screen>());

    dialogAPI.Verify(x => x.ShowDialog(It.IsAny<Screen>(), null, It.IsAny<Dictionary<string, object>>()), Times.Once, "Fail...");
}

问题

XUnit 没有告诉我这个:

Message: Moq.MockException : "Fail..." Expected invocation on the mock once, but was 0 times: x => x.ShowDialog(It.IsAny<Screen>(), null, It.IsAny<Dictionary<String, Object>>())

Configured setups: x => x.ShowDialog(It.IsAny<Screen>(), null, It.IsAny<Dictionary<String, Object>>())

Performed invocations: IWindowManager.ShowDialog(null, null, [[WindowStartupLocation, CenterOwner], [ResizeMode, NoResize]])

我想这与我传递给 Is.Any 方法的数据类型有关,但我不确定。有什么想法吗?

我认为你需要更换:

It.IsAny<Dictionary<string, object>>()

It.IsAny<IDictionary<string, object>>()

Verify调用。因为 ExpandoObject 你传入 ShowDialog 实现了 IDictionary 而不是 Dictionary.

这是我测试过的代码:

public class Screen {

}

public interface IWindowManager {
    bool? ShowDialog(object rootModel, object context = null, IDictionary<string, object> settings = null);
}

public class DialogService {
    private IWindowManager _dialogAPI;
    public DialogService(IWindowManager dialogAPI) {
        _dialogAPI = dialogAPI;
    }
    public virtual bool? ShowDialog(Screen dialog)
    {
        dynamic settings = new ExpandoObject();
        settings.WindowStartupLocation = WindowStartupLocation.CenterOwner;
        settings.ResizeMode = ResizeMode.NoResize;
        return _dialogAPI.ShowDialog(dialog, null, settings);
    }
}

您的代码失败,而将 Dictionary 替换为 IDictionary 则正常:

var dialogAPI = new Mock<IWindowManager>();
dialogAPI.Setup(x => x.ShowDialog(It.IsAny<Screen>(), null, It.IsAny<Dictionary<string, object>>())).Returns(() => true);

var instance = new DialogService(dialogAPI.Object);
instance.ShowDialog(It.IsAny<Screen>());

dialogAPI.Verify(x => x.ShowDialog(It.IsAny<Screen>(), null, It.IsAny<IDictionary<string, object>>()), Times.Once, "Fail...");