Johan Bertilsdotter Johan Bertilsdotter - 2 months ago 16
Vb.net Question

Setup byref parameters in VB from MOQ with C#

The code to be tested looks like this in VB. Simplified

Public Interface IFwCompressor
Function Calculate(ByVal condenserPower As Double,
ByVal evaporatingTemp As Double,
ByVal condensingTemp As Double,
ByRef rotationalSpeed As Double,
ByRef compressorPower As Double,
ByRef electricalPower As Double) As CalculationResult

Enum CalculationResult
ActivateNextCircuit = 3
Off = 2
Ok = 0
UnknownError = -1
MaxRps = -6
End Enum
End Interface

Public Class Compressor
Private ReadOnly _fwCompressor As IFwCompressor

Public Sub New(ByVal fwCompressor As IFwCompressor)
_fwCompressor = fwCompressor
End Sub

Public Function CalculateIntermittentResult(ByVal compressorInput As CompressorIntermittenInput) As StatusAndResult(Of CompressorStatus, CompressorResult)

Dim meanCompressorPower, meanRotationalSpeed, meanElectricalPower As Double

Dim result = _fwCompressor.CalculateIntermittentResult( _
compressorInput.RotationalSpeed,
compressorInput.RunningTimeFraction,
compressorInput.CompressorPower,
meanRotationalSpeed,
meanCompressorPower,
meanElectricalPower)

Return New StatusAndResult(Of CompressorStatus, CompressorResult)(
CompressorStatus.Ok,
New CompressorResult(CompressorRunMode.Intermittent,
meanRotationalSpeed,
meanCompressorPower,
meanElectricalPower))
End Function


The test I've written like this. C# and the MOQ framework.

double meanRotationalSpeed = 15;
double meanCompressorPower = 1000;
double meanElectricalPower = 500;

fwCompressor.Setup(e => e.CalculateIntermittentResult(It.IsAny<double>(),
It.IsAny<double>(),
It.IsAny<double>(),
ref meanRotationalSpeed,
ref meanCompressorPower,
ref meanElectricalPower)).Returns(MaxRps);


My problem is that when the method gets invoke inside
CalculateIntermittentResult
, the parameters
meanRotationalSpeed
,
MeanCompressorPower
,
MeanElectricalPower
and the result return
0
?

ByRef
Parameters in MOQ, is it possible from C# to VB?

Answer

This extention to the MOQ and changing the code to

 .OutCallback((double d1,
                  double d2,
                  double d3,
                  out double v1,
                  out double v2,
                  out double v3) =>
                 {
                   v1 = 15;
                   v2 = 1000;
                   v3 = 500;
                 }).Returns(IFwCompressor.CalculationResult.MaxRps);.OutCallback((double d1,
                  double d2,
                  double d3,
                  out double v1,
                  out double v2,
                  out double v3) =>
                 {
                   v1 = 15;
                   v2 = 1000;
                   v3 = 500;
                 }).Returns(IFwCompressor.CalculationResult.MaxRps);



namespace MoqExtensions
{
using Moq.Language;
using Moq.Language.Flow;
using System.Reflection;

public static class MoqExtensions
{
    public delegate void OutAction<TOut>(out TOut outVal);
    public delegate void OutAction<in T1, TOut>(T1 arg1, out TOut outVal);
    public delegate void OutAction<in T1, TOut1, TOut2>(T1 arg1, out TOut1 outVal1, out TOut2 outVal2);
    public delegate void OutAction<in T1, in T2, in T3, TOut1, TOut2, TOut3>(T1 arg1, T2 arg2, T3 agr3, out TOut1 outVal1, out TOut2 outVal2, out TOut3 outVal3);

    public static IReturnsThrows<TMock, TReturn> OutCallback<TMock, TReturn, TOut>(this ICallback<TMock, TReturn> mock, OutAction<TOut> action)
        where TMock : class
    {
        return OutCallbackInternal(mock, action);
    }

    public static IReturnsThrows<TMock, TReturn> OutCallback<TMock, TReturn, T1, T2, T3, TOut1, TOut2, TOut3>(this ICallback<TMock, TReturn> mock, OutAction<T1, T2, T3, TOut1, TOut2, TOut3> action)
    where TMock : class
    {
        return OutCallbackInternal(mock, action);
    }

    public static IReturnsThrows<TMock, TReturn> OutCallback<TMock, TReturn, T1, TOut1, TOut2>(this ICallback<TMock, TReturn> mock, OutAction<T1, TOut1, TOut2> action)
        where TMock : class
    {
        return OutCallbackInternal(mock, action);
    }

    public static IReturnsThrows<TMock, TReturn> OutCallback<TMock, TReturn, T1, TOut>(this ICallback<TMock, TReturn> mock, OutAction<T1, TOut> action)
        where TMock : class
    {
        return OutCallbackInternal(mock, action);
    }

    private static IReturnsThrows<TMock, TReturn> OutCallbackInternal<TMock, TReturn>(ICallback<TMock, TReturn> mock, object action)
        where TMock : class
    {
        mock.GetType()
            .Assembly.GetType("Moq.MethodCall")
            .InvokeMember("SetCallbackWithArguments", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, mock,
                new[] { action });
        return mock as IReturnsThrows<TMock, TReturn>;
    }
}

}

Comments