亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

單元測試——使用模擬對象做交互測試

2019-11-14 14:17:14
字體:
來源:轉載
供稿:網友

最近在看.net單元測試藝術,我也喜歡單元測試,這里寫一下如何在測試中使用模擬對象。

     開發的過程中,我們都會遇到對象間的依賴,比如依賴數據庫或文件,這時,我們需要使用模擬對象,來進行測試,我們可以手寫模擬對象,當然也可以使用模擬框架。

     假如有這樣的一個需求,當用戶登陸時,我需要對用戶名和密碼進行驗證,然后再將用戶名寫入日志中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MyLogin
    {
        public ILog Log { getset; }
  
        public bool Valid(string userName, string passWord)
        {
            var isValid = userName == "admin" && passWord == "123456";
 
            Log.Write(userName);
 
            return isValid;
        }
    }
 
    public interface ILog
    {
        void Write(string message);
   }
}

     上面的代碼在驗證完登陸信息后,需要向日志中寫入用戶名,由于寫入日志可能依賴于文件或數據庫,我們可能很難進行測試,所以,這里使用模擬對象進行測試。手寫模擬對象,代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[TestFixture]
    public class MyLoginTest
    {
        [Test]
        public void Vaild_Test()
        {
            MyLogin login = new MyLogin();
  
            var log = new TestLog();
  
            login.Log = log;
 
            var userNmae = "admin";
 
            var passWord = "123456";
 
            var isLogin = login.Valid(userNmae, passWord);
 
            Assert.AreEqual(isLogin, true);
 
            Assert.AreEqual(log.Message, userNmae);
        }
   }
    public class TestLog : ILog
    {
        public string Message;
 
        public void Write(string message)
        {
            this.Message = message;
        }
  }

     這里我們定義了一個對象TestLog對象,該對象就是一個模擬對像,繼承了ILog接口。該測試中,一共進行了兩項測試。一項是:驗證用戶名和密碼是否輸入正確。另一項是:驗證用戶寫入日志的信息是否正確(比如應該寫入用戶名,結果把密碼寫入了日志,測試會無法通過)。

     這里我們區分一下模擬對象與樁對象。上一節中,我們講過樁對象的定義,那么模擬對象與樁對象是什么關系呢?

     模擬對象與樁對象在寫法上區別很小,關鍵在于模擬對象需要進行斷言,也就是說模擬對象可以導致測試失敗。樁對象只是為了方便測試所定義的一個對象,不需要進行斷言,所以,樁對象永遠不會導致測試失敗。

     上面的測試中,如果我們去掉最后一行代碼,即我們不進行寫入日志的斷言,則該對象就是一個樁對象。

1
Assert.AreEqual(log.Message, userNmae);

  上面的模擬對象是我們自己寫的,自己寫模擬對象比較費時,我們可以使用模擬框架進行編寫。這里我使用了Rhino Mocks框架。如果要執行下面的代碼,需要下載Rhino.Mocks.dll文件,然后直接引用即可。

測試框架這里我選用了NUnit框架。測試代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[TestFixture]
    public class MyLoginTest
    {
        [Test]
         public void Mock_Vaild_Test()
        {
            MockRepository mock = new MockRepository();
 
            var log = mock.DynamicMock<ILog>();
 
            var userName = "admin";
 
            var passWord = "123456";
 
            using (mock.Record())
            {
                log.Write(userName);
            }
 
            MyLogin login = new MyLogin();
 
            login.Log = log;
 
            var isLogin = login.Valid(userName, passWord);
 
            Assert.AreEqual(isLogin, true);
 
            mock.VerifyAll();
        }

  這里我沒有編寫一個類去繼承ILog接口,而是通過模擬框架,動態生成了一個ILog對象。代碼是這句:

1
2
3
MockRepository mock = new MockRepository();
 
var log = mock.DynamicMock<ILog>();

  這里便生成了Log對象。通過錄制-回放的模式進行模擬對象測試,首先需要定義我們的期望行為,最后驗證實際行為與期望行為是否一致。這里,需要錄制我們期望行為,代碼如下:

1
2
3
4
using (mock.Record())
     {
         log.Write(userName);
     }

  這里我們期望向日志中寫入用戶名。再通過回放來進行驗證,代碼如下:

1
mock.VerifyAll();

  該方法會驗證,期望向日志中寫入的信息與實際向日志中寫入的信息是否一致,如果不一致,測試失敗。

  這里我們便完成了使用模擬框架進行單元測試。如果我們不需要測試日志寫入方法,則把模擬對象換成樁對象就可以了,生成樁對象的方法如下:

1
2
3
MockRepository mock = new MockRepository();
 
var log = mock.Stub<ILog>();

把回放的方法(mock.VerifyAll())去掉,就完成了模擬對象向樁對象的轉變。注意,這里錄制的代碼還是需要的。

總結:編寫模擬對象和樁對象是非常有意義的,使用框架可以幫助我們簡化單元測試。一般情況下,一個測試中,可以有多個樁對象,但最好只有一個模擬對象。模擬對象太多,證明一個測試方法做了太多項測試,不利于維護測試代碼,一旦代碼變改,很容易使單元測試失敗。

下一節,寫一下測試框架的一些常用功能,如:如何模擬異常、如何模擬返回值等。。。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人精品久久二区二区91| 国产人妖伪娘一区91| 国产成人精品综合| 69**夜色精品国产69乱| 亚洲专区国产精品| 欲色天天网综合久久| 疯狂做受xxxx欧美肥白少妇| 国产精品亚洲美女av网站| 国产在线精品成人一区二区三区| 国产欧美精品一区二区三区介绍| 国产亚洲精品一区二555| 俺去亚洲欧洲欧美日韩| 欧美激情精品久久久久久久变态| 国产综合在线视频| 国产丝袜高跟一区| 国产999精品视频| 91久久国产婷婷一区二区| 九九久久综合网站| 亚洲美女性生活视频| 黄色精品在线看| 日韩电影免费在线观看中文字幕| 国产精品手机播放| 45www国产精品网站| 国产免费一区二区三区香蕉精| 成人信息集中地欧美| 日韩av网址在线| 日韩中文视频免费在线观看| 欧美夫妻性生活xx| 国产精品国产三级国产专播精品人| 日韩精品在线观看一区| 国产精品中文字幕久久久| 欧美激情一级二级| 午夜精品久久久久久久99热| 欧美激情在线播放| 久久天堂av综合合色| 国产丝袜一区视频在线观看| 久久综合网hezyo| 久久精品久久久久电影| 亚洲色图色老头| 国产欧美久久久久久| 精品国产1区2区| 美日韩丰满少妇在线观看| 97精品一区二区三区| 日韩久久精品成人| 78m国产成人精品视频| 亚洲乱码国产乱码精品精| 亚洲欧洲日产国码av系列天堂| 91禁国产网站| 97国产精品人人爽人人做| 日韩精品视频中文在线观看| 国产精品美女久久久免费| 欧美影院久久久| 91av成人在线| 久久青草福利网站| 欧美插天视频在线播放| 中文字幕成人在线| 日韩电影中文字幕在线观看| 国产精品直播网红| 国产精品久久激情| 久久久久久亚洲精品| 国产美女主播一区| 亚洲精品福利视频| 亚洲精品电影网站| 亚洲国产成人久久综合| 色偷偷综合社区| 国产一区二区三区免费视频| 九九久久久久久久久激情| 97色在线观看| 精品久久久久久久久久国产| 久久久av免费| 久久九九精品99国产精品| 国产成人精品优优av| 日韩在线视频观看正片免费网站| 欧美成人精品在线视频| 精品福利在线观看| 欧美日韩福利视频| 国产精品久久久久久久久久尿| 欧美乱大交做爰xxxⅹ性3| 国产精品96久久久久久又黄又硬| 久久亚洲国产精品| 亚洲激情自拍图| 91精品国产91久久久久久久久| 欧美中文字幕在线播放| 色综久久综合桃花网| 精品久久久久久中文字幕| 一区二区亚洲精品国产| 欧美激情高清视频| 亚洲另类欧美自拍| 成人日韩av在线| 国产精品一区专区欧美日韩| 国产久一一精品| 日本精品久久电影| 韩国19禁主播vip福利视频| 日本午夜精品理论片a级appf发布| 国产欧美日韩精品专区| 欧美性在线观看| 国产精品三级久久久久久电影| 欧美成人精品xxx| 国产91在线视频| 亚洲欧美日韩精品久久亚洲区| 国产91在线播放九色快色| 国产日韩精品一区二区| 91亚洲永久免费精品| 国产精品日韩一区| 亚洲欧美日韩视频一区| 亚洲国产精品悠悠久久琪琪| 国产精品欧美一区二区三区奶水| 久久91亚洲精品中文字幕| 日韩免费在线免费观看| 亚洲精品国产精品久久清纯直播| 黄色精品在线看| 中文字幕不卡av| 亚洲天堂av高清| 欧美一级黑人aaaaaaa做受| 亚洲国产精品久久| 亚洲成年网站在线观看| 亚洲欧美日韩国产精品| 国产成人亚洲综合91| 久久综合久久八八| 日本中文字幕久久看| 国产精品久久久久久久天堂| 国产在线观看一区二区三区| 91免费在线视频网站| 日韩精品久久久久久久玫瑰园| 日韩av日韩在线观看| 久久精品中文字幕| 国产精品流白浆视频| 国产精品第10页| 成人精品在线视频| 夜夜嗨av色综合久久久综合网| 亚洲欧美一区二区三区情侣bbw| 国产视频久久久久久久| 国产日韩在线播放| 午夜精品免费视频| 亚洲天堂av在线免费观看| 国产成人在线精品| 亚洲永久在线观看| 国产精品美女主播| 国产成人精品久久亚洲高清不卡| 2019中文字幕全在线观看| 亚洲成人国产精品| 性欧美xxxx视频在线观看| 欧美激情视频播放| 亚洲国产美女精品久久久久∴| 国产精品一区二区三区在线播放| 欧美日韩加勒比精品一区| 精品国产欧美一区二区三区成人| 精品国产网站地址| 91精品国产乱码久久久久久蜜臀| 亚洲精品网站在线播放gif| 日韩在线视频一区| 日本久久亚洲电影| 久久久久女教师免费一区| 欧美中文字幕精品| 欧美成人免费全部| 国产日韩精品在线观看| 亚洲黄色免费三级| 成人免费黄色网| 亚洲欧美日韩一区在线| 中文字幕少妇一区二区三区| 国产精品麻豆va在线播放| 久久精品中文字幕一区| 热久久这里只有| 久热精品视频在线观看一区|