Reputation: 5167
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.
Upvotes: 3
Views: 5647
Reputation: 664
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).
Upvotes: 5