How can I mock the CasOperations.GetImpairedNodesFromCASpectrumAsync() method so that it returns the mocked value? Currently, I am getting an exception (shown below the code examples).
I have the following setup:
Class and property to be mocked:
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;
}
}
Test that tries to perform mocking:
[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);
}
Exception thrown in the test:
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.
Allow me to give it a try:
In the setup of the mock you are not trying to mock the behaviour of the BranchCircuitStatusScheduleEntry, but the behaviour of the CasOperations class. So you really need a Mock<CasOperations> object. Or even better, a Mock<ICasOperations> as @Jonesopolis said in his comment.
Besides, in the BranchCircuitStatusScheduleEntry constructor you are initializing both the instance of that class and the instance of CasOperations. It would be better if you initialize the instance of CasOperations outside the BranchCircuitStatusScheduleEntry constructor and pass it as a parameter.
So it would be like this:
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; }
}
Finally, you create your mock, set it up and pass it as a parameter to the BranchCircuitStatusScheduleEntry constructor:
var casMock = new Mock<ICasOperations>();
casMock.Setup(x => x.GetImpairedNodesFromCASpectrumAsync()).ReturnsAsync(mockedNewlyImpairedNodes);
var mock = new Mock<BranchCircuitStatusScheduleEntry>(_application, casMock.Object);
mock.CallBase = true;
Note that maybe this last instance of BranchCircuitStatusScheduleEntry should not be a mock, but a real object (the instance under test).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With