如何在 C# 中对其中的虚拟方法执行抽象 class 的最小起订量测试?
How to perform Moq testing for abstract class in C# for virtual methods inside it?
我想对下面的抽象 Streaming
class 进行测试,它有两个虚拟方法在同一项目的 Asset
class 中被覆盖。这里 SerializeBinary()
方法将对象转换为二进制流,而 DeserializeFromBinary()
方法与 SerializeBinary()
.
相反
如何使用 Moq 编写测试 class 来比较两者?
我从 here:
这是我的代码的一部分:
Streaming
class:
public abstract class Streaming
{
private static int _streamingIDExponent = 41;
public const string MonthLookup = "ABCDEFGHIJK";
public const string ExpiryStringFormat = "ddMMMyyyy";
public const double DefaultTicksPerPoint = 3;
private long _StreamingID;
private int _minQty = DefaultMinimumQty;
public virtual void SerializeBinary(BinaryStreamWriter binaryStreamWriter)
{
binaryStreamWriter.Write(_StreamingID);
binaryStreamWriter.Write(_ex_StreamingID);
binaryStreamWriter.Write(_minQty);
binaryStreamWriter.Write(_extendedProperties.Count);
foreach (KeyValuePair<StreamingPropertyName, StreamingProperty> dictionaryEntry in _extendedProperties)
{
dictionaryEntry.Value.SerializeBinary(binaryStreamWriter);
}
}
public virtual bool DeserializeFromBinary(BinaryStreamReader binaryStreamReader, out string errorString)
{
errorString = string.Empty;
try
{
_StreamingID = binaryStreamReader.ReadInt64();
_exStreamingID = binaryStreamReader.ReadInt64();
_minQty = binaryStreamReader.ReadInt32();
}
catch (Exception oEx)
{
errorString = oEx.Message;
}
return string.IsNullOrEmpty(errorString);
}
Asset
class:
public class Asset : Streaming
{
public override void SerializeBinary(BinaryStreamWriter binaryStreamWriter)
{
base.SerializeBinary(binaryStreamWriter);
}
public override bool DeserializeFromBinary(BinaryStreamReader binaryStreamReader, out string errorString)
{
if (!base.DeserializeFromBinary(binaryStreamReader, out errorString))
return false;
try
{
return true;
}
catch (Exception oEx)
{
errorString = oEx.Message;
return false;
}
}
}
您可以像这样创建流媒体的新模拟 class:
var streamingMock = new Mock<Streaming> { CallBase = true };
调用基础很重要,因为它将在您的具体 class 中执行已实现的代码。
然后你可以通过对象 属性:
调用方法
streamingMock.Object.SerializeBinary(...);
希望对您有所帮助
在您当前的实施中,没有好的方法来测试 Asset
和 Streaming
与 Moq 之间的交互。但是,如果您愿意稍微更改 classes 的实现,您就可以完成它。基本上,您需要将 Streaming
class 方法的逻辑移动到新方法中,然后您可以模拟这些方法。
public abstract class Streaming
{
public virtual void SerializeBinaryCore(BinaryStreamWriter writer)
{
// put the logic from your original SerializeBinary method here...
}
public virtual bool DeserializeFromBinaryCore(BinaryStreamReader reader, out string errorMessage)
{
// put the logic from your original DeserializeFromBinary method here...
}
public abstract void SerializeBinary(BinaryStreamWriter writer);
public abstract bool DeserializeFromBinary(BinaryStreamReader reader, out string errorMessage);
}
然后调整您的 Asset
class 如下:
public class Asset : Streaming
{
public override void SerializeBinary(BinaryStreamWriter writer)
{
SerializeBinaryCore(writer);
}
public override void DeserializeFromBinary(BinaryStreamReader reader, out string errorMessage)
{
var result = DeserializeFromBinaryCore(reader, out errorMessage);
// put the rest of your Asset deserialization logic here...
}
}
在您的测试中,您需要创建一个 Mock<Asset> { CallBase = true }
,然后为 SerializeBinaryCore
和 DeserializeFromBinaryCore
方法创建设置。
我想对下面的抽象 Streaming
class 进行测试,它有两个虚拟方法在同一项目的 Asset
class 中被覆盖。这里 SerializeBinary()
方法将对象转换为二进制流,而 DeserializeFromBinary()
方法与 SerializeBinary()
.
如何使用 Moq 编写测试 class 来比较两者?
我从 here:
这是我的代码的一部分:
Streaming
class:
public abstract class Streaming
{
private static int _streamingIDExponent = 41;
public const string MonthLookup = "ABCDEFGHIJK";
public const string ExpiryStringFormat = "ddMMMyyyy";
public const double DefaultTicksPerPoint = 3;
private long _StreamingID;
private int _minQty = DefaultMinimumQty;
public virtual void SerializeBinary(BinaryStreamWriter binaryStreamWriter)
{
binaryStreamWriter.Write(_StreamingID);
binaryStreamWriter.Write(_ex_StreamingID);
binaryStreamWriter.Write(_minQty);
binaryStreamWriter.Write(_extendedProperties.Count);
foreach (KeyValuePair<StreamingPropertyName, StreamingProperty> dictionaryEntry in _extendedProperties)
{
dictionaryEntry.Value.SerializeBinary(binaryStreamWriter);
}
}
public virtual bool DeserializeFromBinary(BinaryStreamReader binaryStreamReader, out string errorString)
{
errorString = string.Empty;
try
{
_StreamingID = binaryStreamReader.ReadInt64();
_exStreamingID = binaryStreamReader.ReadInt64();
_minQty = binaryStreamReader.ReadInt32();
}
catch (Exception oEx)
{
errorString = oEx.Message;
}
return string.IsNullOrEmpty(errorString);
}
Asset
class:
public class Asset : Streaming
{
public override void SerializeBinary(BinaryStreamWriter binaryStreamWriter)
{
base.SerializeBinary(binaryStreamWriter);
}
public override bool DeserializeFromBinary(BinaryStreamReader binaryStreamReader, out string errorString)
{
if (!base.DeserializeFromBinary(binaryStreamReader, out errorString))
return false;
try
{
return true;
}
catch (Exception oEx)
{
errorString = oEx.Message;
return false;
}
}
}
您可以像这样创建流媒体的新模拟 class:
var streamingMock = new Mock<Streaming> { CallBase = true };
调用基础很重要,因为它将在您的具体 class 中执行已实现的代码。 然后你可以通过对象 属性:
调用方法streamingMock.Object.SerializeBinary(...);
希望对您有所帮助
在您当前的实施中,没有好的方法来测试 Asset
和 Streaming
与 Moq 之间的交互。但是,如果您愿意稍微更改 classes 的实现,您就可以完成它。基本上,您需要将 Streaming
class 方法的逻辑移动到新方法中,然后您可以模拟这些方法。
public abstract class Streaming
{
public virtual void SerializeBinaryCore(BinaryStreamWriter writer)
{
// put the logic from your original SerializeBinary method here...
}
public virtual bool DeserializeFromBinaryCore(BinaryStreamReader reader, out string errorMessage)
{
// put the logic from your original DeserializeFromBinary method here...
}
public abstract void SerializeBinary(BinaryStreamWriter writer);
public abstract bool DeserializeFromBinary(BinaryStreamReader reader, out string errorMessage);
}
然后调整您的 Asset
class 如下:
public class Asset : Streaming
{
public override void SerializeBinary(BinaryStreamWriter writer)
{
SerializeBinaryCore(writer);
}
public override void DeserializeFromBinary(BinaryStreamReader reader, out string errorMessage)
{
var result = DeserializeFromBinaryCore(reader, out errorMessage);
// put the rest of your Asset deserialization logic here...
}
}
在您的测试中,您需要创建一个 Mock<Asset> { CallBase = true }
,然后为 SerializeBinaryCore
和 DeserializeFromBinaryCore
方法创建设置。