65.9K
CodeProject 正在变化。 阅读更多。
Home

使用序列化模拟程序集

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.60/5 (2投票s)

2004 年 10 月 17 日

3分钟阅读

viewsIcon

28494

downloadIcon

123

一种模拟复杂类的方法。

Sample Image - showing the concept in action!

引言

在团队环境中工作时,诸如有限的许可证密钥、安全性或网络访问等因素可能会阻碍测试环境的创建。 在最近的一个项目中,我的要求之一是与现有的 .NET 组件进行交互。 现有的组件无法在我的异地办公环境中复制,并且现有的安全策略不允许网络访问。 代码编写和接口测试看起来非常困难。

在本文中,我将介绍一种我用来克服此问题的方法。 简而言之,我使用的方法是从接口查询(函数调用)中捕获输出,然后序列化结果,将其写入文件,并通过电子邮件发送到我的办公室。 稍后,当我在异地需要模拟原始组件时,我调用一个具有与原始组件相同的参数和接口的替代函数,并反序列化我存储的结果。

此方法允许我完全模拟特定测试的接口。 实际概念非常简单,并且结果在提供临时测试环境方面非常有效。

首先,快速浏览一下我希望模拟的类...

为了便于解释,我创建了一个具有复杂结果集的类。 实际的内部处理并不重要,事实上,对于这个例子来说,我是否可以查看内部工作原理并不重要。

Public Class clsMyResult
    'clsMyResult is complex (output) class, 
    'the result am interested in emulating.
    Public myDS As DataSet
    Public strDesc As String
    Public myCounter As Int16 = 0
End Class

Public Class clsOriginalClassIWishToEmulate
    'this is the original class I wish to emulate - 
    'but I want to pretend I don't know 
    '(or have access to) the internal workings
    Public Function MakeResult(ByVal newTables As Int16) As clsMyResult
        Dim myResult As New clsMyResult
        Dim localDS As New DataSet
        For y As Int16 = 1 To newTables
            Dim thisTable As New DataTable("table" & y)
            thisTable.Columns.Add("tab:" & y & "-col")
            Dim myDataRow As DataRow
            For x As Int16 = 1 To 10
                myDataRow = thisTable.NewRow
                myDataRow(0) = "table:" & y & " row:" & x
                thisTable.Rows.Add(myDataRow)
            Next
            localDS.Tables.Add(thisTable)
            myResult.myCounter += 1
        Next
        myResult.myDS = localDS
        myResult.strDesc = "There are " & myResult.myCounter & _
                                        " tables in the dataset"
        Return myResult

    End Function
End Class

调用 clsOriginalClassIWishToEmulate.MakeResult 将生成一个包含已填充的 DataSet、一个文本字符串以及 DataSet 中表数量的计数器的输出类。

捕获原始类的输出

这种仿真的第一步是访问原始类——例如在本地开发者计算机上,并针对它运行查询。

在我的例子中,我将创建原始类的一个实例,并调用我想要模拟的函数。 我将传递给函数 int16 值 10:myOriginalClass.MakeResult(10)

Private Sub Serialize_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles Button1.Click
    ' I want to use clsOriginalClassIWishToEmulate but
    ' I cannot because of access restrictions
    ' First thing to do is to instantiate the class
    ' and the results I want to copy
    Dim myOrginalClass As New clsOriginalClassIWishToEmulate
    Dim myResult As clsMyResult 
    'myResult is the output of clsOriginalClassIWishToEmulate.
    'Let's decide we want to emulate as close as possible 
    'the class which is fed a value of "10"
    'Next, let's get the result value
    myResult = myOrginalClass.MakeResult(10)
    'define an file to write the result to...
    Dim myStreamWriter As StreamWriter
    myStreamWriter = New StreamWriter("myresult.xml")
    'and serialize the class
    Dim mySerializer As New XmlSerializer(GetType(clsMyResult))
    mySerializer.Serialize(myStreamWriter, myResult)
    myStreamWriter.Close()
End Sub

在函数返回值后,我将结果序列化为 XML 文件。 请注意,我需要知道响应的结构,此代码段才能工作。

模拟原始类接口

下一步需要创建一个与原始类具有相同参数的替代类。 此类打开存储的 XML 文件,并返回一个实际值(在本例中,对于“10”)。

Public Class clsEmulatedClass
    Public Function MakeResult(ByVal newTables As Int16) As clsMyResult
        'the point of this class is to mimic the original - but in this case 
        'will only mimic correct functions for input value "10"
        Dim myResult As New clsMyResult
        'setup the stream reader and xml serializetion object
        Dim myStreamReader As StreamReader
        Dim mySerializer As New XmlSerializer(GetType(clsMyResult))
        'load the saved XML file
        myStreamReader = New StreamReader("myresult.xml")
        myResult = mySerializer.Deserialize(myStreamReader)
        myStreamReader.Close()
        Return myResult
    End Function
End Class

使用新函数

新创建的函数将与原始函数的操作相同,对于我们已模拟的函数。 当然,返回的类仅对于特定的一组输入值才是正确的。

增强功能

此示例的进一步添加可能包括

  • 存储多个输入的结果(模拟类可以从具有匹配输入值的示例中返回结果);
  • 模拟属性;
  • 复制原始类命名空间的相关方面。

结论

此处显示的方法允许创建模拟类。 当原始类由于安全性、网络或许可限制而不可用时,这尤其有用。 虽然该方法非常简单,但它可以允许创建原本不可能的开发和测试环境。

祝你好运,编程愉快!!

© . All rights reserved.