[英]Calling VB6 method from C# from dynamic object with ByRef and optional Parameters
[英]Setup byref parameters in VB from MOQ with C#
要测试的代码在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
?
MOQ中的ByRef
参数,是否可以从C#到VB?
我想我还是应该回答这个问题。 如果您使用的是最新版的Moq(版本4),则它支持ref参数。 如果您查看该文档,则只要该参数与在System Under Tests中调用时传入的实例相同,它就支持在ref参数上进行设置。
https://github.com/Moq/moq4/wiki/快速入门
// 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);
如果您使用的是double数据类型,则它的值必须与被测系统中使用的值相同。
//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,参考上的设置就应该起作用。
如果您使用的是Moq 3,则不支持ref参数。 查看Moq 4的新功能https://github.com/moq/moq4
“对out / ref参数的直观支持”
另请参阅Moq中的分配输出/参考参数
扩展到最小起订量并将代码更改为
.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>;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.