在VB中使用c#从MOQ中设置ref参数

本文关键字:MOQ 设置 ref 参数 VB | 更新日期: 2023-09-27 18:07:55

要测试的代码在VB中看起来像这样。简化的

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

测试我是这样写的。c#和MOQ框架。

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);

我的问题是,当方法在CalculateIntermittentResult内部调用时,参数meanRotationalSpeed, MeanCompressorPower, MeanElectricalPower和结果返回0 ?

ByRef参数在MOQ,是可能的,从c#到VB?

在VB中使用c#从MOQ中设置ref参数

我想我应该回答这个问题。如果您使用的是最新版本的Moq(版本4),它支持ref参数。如果你看一下文档,它支持在ref参数上设置,只要该参数是在System Under Tests中调用时传入的同一个实例。

https://github.com/Moq/moq4/wiki/Quickstart

  // ref arguments
  var instance = new Bar();
  // Only matches if the ref argument to the invocation is the same instance
  mock.Setup(foo => foo.Submit(ref instance)).Returns(true);

如果您使用双数据类型,它必须与您在测试系统中使用的值相同。

    //method under test
    public int CallRef()
    {
        double d1 = 10;
        var r1 = _foo.DoRef(ref d1);
        return r1;
    }
    //test method
    [TestMethod]
    public void TestMethod1()
    {
        double dt = 10;
        var fooStub = new Mock<IFoo>();
        fooStub.Setup(x => x.DoRef(ref dt)).Returns(7);
        var s = new S(fooStub.Object);
        var r1 = s.CallRef(); 
    }

只要dt为10,ref上的设置就应该工作。

如果你使用Moq 3,我不认为ref参数已被支持。看看Moq 4有什么新功能https://github.com/moq/moq4

" out/ref参数的直观支持"

见也在Moq中分配out/ref参数

此扩展到最小起订量并更改代码

 .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>;
    }
}

}