autofixture簡介
有了單元測試框架加上Moq(后面我們會用單獨章節來介紹moq),可以說測試問題基上都能搞定了.然而有了AutoFixture對單元測試來說可以說是如虎添翼,AutoFixture並且它能與moq,rhinomock等框架結合,對單元測試帶來的便捷性,可維護性和擴展性更是難以言表,只有用用了才知道.
說了這么多,還沒有介紹AutoFixture是干什么的,其實AutoFixture就是一個假數據填充工具.
其實不論是Nunit還是Xunit都有數據填充功能,並且大部分時候都能滿足需求.然而通過我們前面的介紹就會知道有以下問題:
- 不論是vlues注解還是TestCase注解都沒有類型約束,這就可能會造成運行時錯誤.
- 基於注解的值都只能是Const值,如果需要復雜類型就需要定義一個類型做為Source為當前操作提供值.
- 與Nunit和Xunit生成的填充數據相比,Autofixture可以生成符合驗證規則的數據(基於system.componentmodel.annotations名稱空間下的注解約束),這在集成測試里幫助很大,對於有着非常復雜模型驗證的接口來說,手工制造出符合模型驗證規則的數據往往是非常痛苦的.
- Autofixture可以生成一組符合驗證規則的數據,這樣在測試的時候增加了樣本數據的隨機性,大大提升了測試的覆蓋面.
Moq測試雖然極大方便了測試,但是也會有一些問題:
-
對於比較復雜的web項目,往往一個業務邏輯可能要消費十個幾個甚至幾十個數據接口,如果業務不是很成熟可能需要不斷的來調整這些接口,這里的修改同時單元測試方法也需要修改(因為這些接口多數時候是通過構造函數注入的,構造函數參數數量的變動會導致調用者也需要做相應調整)
-
雖然Moq也能夠模擬類對象,但是限制非常多,我們不可能為了測試把所有的方法和屬性都加上abstract或者virtual.
而autofixture則可以很好的解決這些問題.這樣極大增加代碼的可維護性和擴展性.
AutoFixture並不是對moq的替代,它只能填充對象,而不能模擬對象,但是它可以與moq框架結合實現更強大的功能.
autofixture安裝
autofixture安裝非常簡單,我們在Nuget里搜索autofixture,第一個就是它點擊安裝即可.
關於autofixture與moq結合需要的包在后面講到的時候再安裝,這里先略過.
AutoFixture 自動為Nunit填充數據
要使AutoFixture與Nunit結合,首先我們需要安裝特定的包.
在Nuget里輸入AutoFixture.Nunit3,會出現以下選項
由於我們使用的是Nunit3,因此我們選擇第一個安裝.
AutoFixture還可以與Xunit結合.在Nuget里搜索AutoFixture.xunit2便可以搜索到AutoFixture與Xunit結合的框架.與Xunit結果的用法與Nunit差不多,只是需要注意Xunit數據測試方法需要Theory注解.
我們新建一個名為FixtureTest
並引入AutoFixture.NUnit3;
名稱空間
代碼如下
[TestFixture]
public class FixtureTest
{
[Test]
[AutoData]
public void FixValueTest(int a, int b)
{
var result = Add(a , b);
Assert.AreEqual(a + b, result);
}
int Add(int x, int y)
{
return x + y;
}
}
這里與平時的單元測試相比,多了一個AutoData注解,有了AutoData注解,AutoFixture便可以給當前測試提供值了.
我們斷點調試一下看看a和b的值
我們可以看到a和b都被賦予了隨機的值.
我們把測試代碼改為如下
[Test]
[AutoData]
public void FixValueTest(Person p1, Person p2)
{
var result = Add(p1.Age , p2.Age);
Assert.AreEqual(p1.Age + p2.Age, result);
}
我們再斷點調試一下看看是否有值
復雜對象它也能填充!這樣就免去了為了使用復雜對象需要額外寫很多source繁瑣.
我們把代碼改成如下
[Test]
[AutoData]
public void FixValueTest(IEnumerable<Person> people)
{
var ages = people.Sum(a => a.Age);
}
我們看看此時會有什么結果
通過監視容器可以看到,AutoFixture生成了一個包含三個元素的對象.
這簡直是太方便了,autofixture自動填充值不但減少了運行時可能的類型錯誤,還有極大的擴展性,如果我們在測試方法上添加其它參數,它仍然能夠自動填充.而使用Nunit自身帶的TestCase如果參數減少,里面指定的值也要減少,否則會拋出運行時異常.
通過以上我們可以看到,AutoFixture可以生成各種類型的對象,它可以創建集合對象對我們測試來說尤其有用,免去了手動創建的麻煩.但是我們同時也看到,基於注解的方法生成集合時只生成了三個,實際上要模擬數據庫是的數據測試一些行為我們可能需要更多的元素.這里就需要對AutoFixture本身進行配置.這是基於注解的方法無法完成的.