【问题标题】:Method with Object argument won't accept anything other than an Object带有 Object 参数的方法不会接受除 Object 以外的任何东西
【发布时间】:2009-10-06 16:10:04
【问题描述】:

我们在类 InitializerFactory 中有一个带有以下签名的 VB.net 函数:

Public Shared Function Create(ByRef ui As Object) As IModeInitializer

我正在尝试通过传入一个模拟的 ui(使用 Rhino Mocks)来测试这个功能:

MainForm ui = mocks.StrictMock<MainForm>();
IModeInitializer item = InitializerFactory.Create(ref ui);

当尝试将 ui 作为参数传递时,我收到以下错误:

  • 最好的重载方法匹配 'InitializerFactory.Create(ref object)' 有一些无效参数
  • 参数“1”:无法从“ref MainForm”转换为“ref object”

理想情况下,解决方案是在 UI(或其类 MainForm)上提取一个接口,但这无论如何都不可行 - 这是一个非常臃肿的类。

我也不能将 ui 声明为 Object,否则我不能模拟其中的方法,因为这些方法不属于 Object 类型。

我的问题是——我做错了什么?

【问题讨论】:

    标签: c# unit-testing rhino-mocks parameters


    【解决方案1】:

    这仅仅是因为 ref 参数语法。问题是该函数必须能够设置任何类型的对象,因为它是一个 by ref 参数。您不能只将一个对 MainForm 的引用传递给它,这正是您正在尝试的。

    不幸的是,这是一个很难使用的 API。

    您可以通过先将实例分配给对象来处理此问题:

    MainForm ui = mocks.StrictMock<MainForm>();
    object uiObj = ui;
    IModeInitializer item = InitializerFactory.Create(ref uiObj);
    if (uiObj != ui) { 
        // Handle the case where the reference changed!
        ui = uiObj as MainForm; // May be null, if it's no longer a "MainForm"
    }
    

    如果您想完全理解这一点,可以阅读Covariance and Contravariance

    【讨论】:

    • 我已经尝试过了,但随后在 NUnit 中出现以下错误:System.InvalidOperationException : The object '' is not a mocked object。 我假设它正在谈论 uiObj,因为它不仅仅是一个 Object 而不是一个模拟对象。
    • 如果你能说出错误发生在哪里,那真的很有帮助。但我同意 Reed - 这听起来像是一个可怕的 API。它真的必须有一个 by-ref 参数吗?
    • @MunkiPhD:这不是问题所在。强制转换和分配给对象不会改变对象的实际类型。方法内部还有其他问题。
    • 是的,API 在某些领域并不是最好的,但“它就是这样”。
    猜你喜欢
    • 1970-01-01
    • 2016-09-12
    • 2017-05-16
    • 2016-01-05
    • 1970-01-01
    • 1970-01-01
    • 2018-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多