C# 用XUnit测试动态expando

C# 用XUnit测试动态expando,c#,unit-testing,dynamic,caliburn.micro,xunit.net,C#,Unit Testing,Dynamic,Caliburn.micro,Xunit.net,因此,我正在尝试测试一个来自正在调用的注入对话框API的方法(使用CaliburnMicro MVVM框架) 方法 public bool? ShowDialog(Screen dialog) { dynamic settings = new ExpandoObject(); settings.WindowStartupLocation = WindowStartupLocation.CenterOwner; settings.ResizeMode = ResizeMod

因此,我正在尝试测试一个来自正在调用的注入对话框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...");
}
[事实]
公共无效对话框ServiceCallApitoshowDialog()
{
var dialogAPI=newmock();
dialogAPI.Setup(x=>x.ShowDialog(It.IsAny(),null,It.IsAny())。返回(()=>true);
var实例=新的DialogService(dialogAPI.Object);
ShowDialog(It.IsAny());
Verify(x=>x.ShowDialog(It.IsAny(),null,It.IsAny()),Times.Once,“Fail…”);
}
问题

XUnit没有告诉我:

消息:Moq.MockException:“Fail…”应在mock上调用 一次,但是0次:
x=>x.ShowDialog(It.IsAny(),null,
It.IsAny())

配置的设置:
x=>x.ShowDialog(It.IsAny(),null,
It.IsAny())

执行的调用:IWindowManager.ShowDialog(null,null, [[WindowsStartUpLocation,CenterOwner],[ResizeMode,NoResize]]


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

我认为您需要更换:

It.IsAny<Dictionary<string, object>>()
IDictionary
替换
Dictionary
时,代码失败:

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...");
var dialogAPI=newmock();
dialogAPI.Setup(x=>x.ShowDialog(It.IsAny(),null,It.IsAny())。返回(()=>true);
var实例=新的DialogService(dialogAPI.Object);
ShowDialog(It.IsAny());
Verify(x=>x.ShowDialog(It.IsAny(),null,It.IsAny()),Times.Once,“Fail…”);

我已经这样试过了;但它不起作用。我已经通过使用Dictionary参数而不是它暂时解决了问题。IsAny,但这不是可选的解决方案。奇怪的是,我在发布之前验证了。你能发布IWindowManager.ShowDialog的准确签名吗?
bool?ShowDialog(对象根模型,对象上下文=null,IDictionary设置=null)
@ErreEfe仍然无法复制(我的意思是,使用您的代码,它会失败,但替换为
IDictionary
会修复它)。包括我在answer.Evk中测试的代码。解决了,谢谢。这是一个很难解决的问题。为什么?有两个
Screen
类别。一个是Caliburn及其对话API使用的外部屏幕。我正在测试的软件中使用的另一个。Moq告诉我,预期结果是调用一个方法,该方法预期与服务初始化相同的
Screen
参数,但有两个不同的参数是问题所在。实际上,您并没有将值传递给被测试的方法。它仅用于Moq表达式中。如果您检查
ShowDialog
的结果,它也将是
null
。如果我只是为了测试目的而用一个具体的屏幕替换它,这并不重要。问题在于
ShowDialog
的设置与其执行情况有关。是的,但我没有检查结果(这是另一个单元测试),我只是检查是否有人调用WindowManager。我认为如果模拟配置正确并按预期执行,结果将为真。
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);
    }
}
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...");