Moq - 不能模拟 class 属性 的方法 return 值
Moq - Can't mock a class property's method return value
如何模拟 CasOperations.GetImpairedNodesFromCASpectrumAsync()
方法,使其 returns 成为模拟值?目前,我遇到异常(代码示例下方显示)。
我有以下设置:
Class 和 属性 被嘲笑:
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);
}
测试抛出异常:
An exception of type
'Castle.DynamicProxy.InvalidProxyConstructorArgumentsException'
occurred in Moq.dll but was not handled in user code Additional
information: Can not instantiate proxy of class:
NWatch.NetworkCircuits.CasOperations. Could not find a parameterless
constructor.
请允许我试一试:
在模拟设置中,您不是要模拟 BranchCircuitStatusScheduleEntry
的行为,而是要模拟 CasOperations
class 的行为。所以你真的需要一个 Mock<CasOperations>
对象。甚至更好,正如@Jonesopolis 在他的评论中所说的 Mock<ICasOperations>
。
此外,在 BranchCircuitStatusScheduleEntry
构造函数中,您正在初始化 class 的实例和 CasOperations
的实例。如果在 BranchCircuitStatusScheduleEntry
构造函数之外初始化 CasOperations
的实例并将其作为参数传递会更好。
所以它会是这样的:
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
的最后一个实例不应该是模拟的,而是真实的对象(被测实例)。
如何模拟 CasOperations.GetImpairedNodesFromCASpectrumAsync()
方法,使其 returns 成为模拟值?目前,我遇到异常(代码示例下方显示)。
我有以下设置:
Class 和 属性 被嘲笑:
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);
}
测试抛出异常:
An exception of type 'Castle.DynamicProxy.InvalidProxyConstructorArgumentsException' occurred in Moq.dll but was not handled in user code Additional information: Can not instantiate proxy of class: NWatch.NetworkCircuits.CasOperations. Could not find a parameterless constructor.
请允许我试一试:
在模拟设置中,您不是要模拟 BranchCircuitStatusScheduleEntry
的行为,而是要模拟 CasOperations
class 的行为。所以你真的需要一个 Mock<CasOperations>
对象。甚至更好,正如@Jonesopolis 在他的评论中所说的 Mock<ICasOperations>
。
此外,在 BranchCircuitStatusScheduleEntry
构造函数中,您正在初始化 class 的实例和 CasOperations
的实例。如果在 BranchCircuitStatusScheduleEntry
构造函数之外初始化 CasOperations
的实例并将其作为参数传递会更好。
所以它会是这样的:
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
的最后一个实例不应该是模拟的,而是真实的对象(被测实例)。