Moq - 无法模拟类属性的方法返回值

时间:2016-05-23 20:53:06

标签: c# moq

如何模拟CasOperations.GetImpairedNodesFromCASpectrumAsync()方法以便返回模拟值?目前,我得到一个例外(如下面的代码示例所示)。

我有以下设置:

要嘲笑的类和属性:

public class BranchCircuitStatusScheduleEntry : NWatchCustomScheduleEntryBase, INWatchCustomScheduleEntry
{
    public BranchCircuitStatusScheduleEntry(INWatchSchedulerApplication application)
        : base(application, DevOpsScheduleFrequency.Minute, 15, 0, DevOpsScheduleFlags.Always)
    {
        // Some initialization for below properties
        CasOperations = new CasOperations(cas, EntityService, IsBranchesOnly);
    }

    public CasOperations CasOperations { get; private set; }

}

public class CasOperations
{
    public CasOperations(CasApi casApi, BranchCircuitEntityService entityService, bool isBranchesOnly)
    {
        CAS = casApi;
        this.entityService = entityService;
        this.isBranchesOnly = isBranchesOnly;
    }
}

尝试执行模拟的测试:

[TestMethod]
public void DownNodeRediscoveredInSpectrum()
{
    var mock = new Mock<BranchCircuitStatusScheduleEntry>(_application);
    mock.CallBase = true;

    // Spectrum's artificial response with a model with the same name, but a "new" model handle
    var mockedNewlyImpairedNodes = new NetworkDeviceNodeStatus[]
    {
        new NetworkDeviceNodeStatus
        {
            // Not important
        }
    };

    mock.Setup(x =>
        x.CasOperations.GetImpairedNodesFromCASpectrumAsync()).ReturnsAsync(mockedNewlyImpairedNodes);
}

测试中抛出异常:

  

类型的例外   'Castle.DynamicProxy.InvalidProxyConstructorArgumentsException'   发生在Moq.dll但未在用户代码中处理   信息:无法实例化类的代理:   NWatch.NetworkCircuits.CasOperations。找不到无参数   构造

1 个答案:

答案 0 :(得分:4)

请允许我试一试:

在模拟的设置中,您不是试图模仿BranchCircuitStatusScheduleEntry的行为,而是模拟CasOperations类的行为。所以你真的需要一个Mock<CasOperations>对象。或者甚至更好,@ {Jonesopolis Mock<ICasOperations>在他的评论中说。

此外,在BranchCircuitStatusScheduleEntry构造函数中,您正在初始化该类的实例和CasOperations的实例。如果在CasOperations构造函数之外初始化BranchCircuitStatusScheduleEntry的实例并将其作为参数传递,那会更好。

所以它会是这样的:

public class BranchCircuitStatusScheduleEntry : NWatchCustomScheduleEntryBase, INWatchCustomScheduleEntry
{
    public BranchCircuitStatusScheduleEntry(INWatchSchedulerApplication application, ICasOperations casOperations)
        : base(application, DevOpsScheduleFrequency.Minute, 15, 0, DevOpsScheduleFlags.Always)
    {
        CasOperations = casoperations;
    }

    public CasOperations CasOperations { get; private set; }
}

最后,您创建模拟,设置并将其作为参数传递给BranchCircuitStatusScheduleEntry构造函数:

var casMock = new Mock<ICasOperations>();
casMock.Setup(x => x.GetImpairedNodesFromCASpectrumAsync()).ReturnsAsync(mockedNewlyImpairedNodes);

var mock = new Mock<BranchCircuitStatusScheduleEntry>(_application, casMock.Object);
mock.CallBase = true;

请注意,BranchCircuitStatusScheduleEntry的最后一个实例可能不是模拟,而是真实对象(正在测试的实例)。