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

通常单元测试需要访问受测类的私有方法或属性,一般需要使用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);
}


 

 

你可能感兴趣的:(单元测试)