简体   繁体   English

如何在C#中针对其中的虚拟方法执行抽象类的Moq测试?

[英]How to perform Moq testing for abstract class in C# for virtual methods inside it?

I would like to perform testing for below abstract Streaming class which has two virtual methods that are overridden in the Asset class in same project. 我想对下面的抽象Streaming类执行测试,该类具有在同一个项目的Asset类中被覆盖的两个虚拟方法。 Here the SerializeBinary() method converts an object into binary streams and DeserializeFromBinary() method does the opposite of SerializeBinary() . 在这里, SerializeBinary()方法将对象转换为二进制流,而DeserializeFromBinary()方法的作用与SerializeBinary()相反。

How to write test class for comparing both using Moq? 如何编写测试类以使用Moq进行比较?

I go through from here: 我从这里经过

This is part of my code: 这是我的代码的一部分:

Streaming class: Streaming类:

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: Asset类别:

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

you can create a new Mock of your Streaming class like this: 您可以像这样创建Streaming类的新Mock:

var streamingMock = new Mock<Streaming> { CallBase = true };

The call base is important because it will then execute the implemented code in your concrete class. 调用基很重要,因为它随后将在您的具体类中执行已实现的代码。 Then you can call the methods via the Object property: 然后,您可以通过Object属性调用方法:

streamingMock.Object.SerializeBinary(...);

Hope this helps 希望这可以帮助

There's no good way to test the interaction between Asset and Streaming with Moq in your current implementation. 在当前的实现中,没有很好的方法来测试AssetStreaming与Moq之间的交互。 However, if you're willing to change the implementation of the classes just a bit, you can get it done. 但是,如果您愿意稍微更改这些类的实现,则可以完成。 Basically, you'll want to move the logic of the Streaming class's methods into new methods, and you can then mock those. 基本上,您将需要将Streaming类的方法的逻辑移到新方法中,然后可以对它们进行模拟。

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

And then tweak your Asset class as follows: 然后如下调整您的Asset类:

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

In your test, you need to create a Mock<Asset> { CallBase = true } , and then create setups for the SerializeBinaryCore and DeserializeFromBinaryCore methods. 在测试中,您需要创建Mock<Asset> { CallBase = true } ,然后为SerializeBinaryCoreDeserializeFromBinaryCore方法创建设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM