• 如何在单元测试编码实现类的访问器?这里给出一个答案


    通常单元测试需要访问受测类的私有方法或属性,一般需要使用VSTS自动生成的访问器,但是对于该类的父类私有属性就无法访问了,这也是上一篇博文提到的状况。其实我们还可以自己编写访问器,这样就不需要受到系统生成的访问器的束缚(由于生成的访问器没有源码无法修改)。下文就是一个范例(受测项目BankDemo.csproj,程序集BankDemo.exe):

    ========受测类的实现代码:========

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace BankDemo
    {
        
    public class BankAccount
        {
            
    private int _accountNo;
            
    private float _currentBalance;
            
    private static float _bankAsset;
            
    private static int _newUniqueAccountNo;

            
    private static int GetUniqueAccountNo
            {
                
    get { return ++_newUniqueAccountNo; }
            }

            
    private float CurrentBalance
            {
                
    get { return _currentBalance; }
                
    set { _currentBalance = value; }
            }

            
    // Constructors for new account
            private BankAccount(float initialBalance)
            {
                
    this._accountNo = GetUniqueAccountNo;
                
    this._currentBalance = initialBalance;
                _bankAsset 
    += initialBalance;
            }

            
    // Methods
            private float DepositMoney(float depositAmount)
            {
                
    this.CurrentBalance += depositAmount;
                _bankAsset 
    += depositAmount;
                
    return this.CurrentBalance;
            }

            
    private float WithdrawMoney(float withdrawAmount)
            {
                
    this.CurrentBalance -= withdrawAmount;
                _bankAsset 
    -= withdrawAmount;
                
    return this.CurrentBalance;
            }

            
    private static float BankAsset()
            {
                
    return _bankAsset;
            }

        }


    }

    ========访问器代码可以这样实现:========  

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.VisualStudio.TestTools.UnitTesting;


    namespace TestProject1
    {
        
    class BankAccountAccessor
        {
            PrivateObject _privateObject;
            
    static PrivateType _privateType = new PrivateType("BankDemo""BankDemo.BankAccount");


            
    public BankAccountAccessor(object target)
            {
                _privateObject 
    = new PrivateObject(target, _privateType);
            }


            
    public static object CreatePrivate(float initialBalance)
            {
                
    object[] args = new object[] { initialBalance };
                PrivateObject priv_obj 
    = new PrivateObject("BankDemo""BankDemo.BankAccount"new System.Type[] { typeof(float) }, args);
                
    return priv_obj.Target;
            }

            
    public float DepositMoney(float depositAmount)
            {
                
    object[] args = new object[] { depositAmount };

                
    return ((float)(_privateObject.Invoke("DepositMoney"new Type[] { typeof(float) }, args)));
            }

            
    public float WithdrawMoney(float withdrawAmount)
            {
                
    object[] args = new object[] { withdrawAmount };

                
    return ((float)(_privateObject.Invoke("WithdrawMoney"new Type[] { typeof(float) }, args)));
            }

            
    public static float BankAsset()
            {
                
    object[] args = new object[0];

                
    return ((float)(_privateType.InvokeStatic("BankAsset"new System.Type[0], args)));
            }

            
    public float CurrentBalance
            {
                
    get {     return ((float)(_privateObject.GetProperty("CurrentBalance")));     }

                
    set {     _privateObject.SetProperty("CurrentBalance", value);     }
            }

            
    public static int GetUniqueAccountNo
            {
                
    get {     return ((int)(_privateType.GetStaticProperty("GetUniqueAccountNo")));     }
            }

            public int _accountNo
            {
                get { return ((int)(_privateObject.GetField("_accountNo"))); }

                set { _privateObject.SetField("_accountNo", value); }
            }
        }
    }

    ========单元测试就是如下(这里仅仅举其中一个私有方法测试为例):========

    [TestMethod()]
    public void WithdrawMoneyTest()
    {
                
    float initBalance = 5000f;
                
    object param0 = BankAccountAccessor.CreatePrivate(initBalance);
                BankAccountAccessor target 
    = new BankAccountAccessor(param0);
                
    float withdrawAmount = 100F;
                
    float expected = initBalance - withdrawAmount;
                
    float actual;
                actual 
    = target.WithdrawMoney(withdrawAmount);
                Assert.AreEqual(expected, actual);
    }


  • 相关阅读:
    [Swift]LeetCode811. 子域名访问计数 | Subdomain Visit Count
    [Objective-C语言教程]程序结构(3)
    [Objective-C语言教程]开发环境设置(2)
    [Objective-C语言教程]简介(1)
    [Swift]LeetCode810. 黑板异或游戏 | Chalkboard XOR Game
    [Swift]LeetCode809. 情感丰富的文字 | Expressive Words
    [Swift]LeetCode808. 分汤 | Soup Servings
    转:用ANT执行SQL
    转:让开发自动化: 实现自动化数据库迁移
    转 让开发自动化: 使用自动化加速部署
  • 原文地址:https://www.cnblogs.com/chriskwok/p/1250824.html
Copyright © 2020-2023  润新知