2012-02-22 76 views
4

我得到了一些我想測試的業務邏輯代碼。
目前我只知道如何在沒有其他依賴的邏輯代碼上編寫單元測試。如何爲此業務邏輯代碼編寫可靠的單元測試?

任何人都可以指出我如何測試這個功能的好方向,也許舉個例子嗎?

是測試這個集成測試的唯一方法,還是我必須使用模擬/存根?

/// <summary> 
/// Gets the scan face file by a MemberID 
/// </summary> 
/// <param name="MemberID">The ID of a member</param> 
/// <returns>A scan face file in byte array format</returns> 
public byte[] GetScanFileFaceByMemberID(int MemberID) 
{ 
    byte[] scanFileFace; 

    using (ProductionEntities entityContext = new ProductionEntities()) 
    { 
     scanFileFace = (from scan in entityContext.tblScan 
        where scan.MEMBERID == MemberID 
        select scan.scanFileFace).Single(); 
    } 

    return scanFileFace; 
} 

變化(I實現存儲庫&犀牛製品):

BL:

public byte[] GetScanFileFaceByMemberID(int MemberID) 
{ 
    byte[] scanFileFace; 

    var query = Repository.GetAll<tblScan>().Where(bl => bl.MEMBERID == MemberID).Single(); 

    scanFileFace = query.scanFileFace; 

    return scanFileFace; 
} 

單元測試:

[TestMethod] 
public void GetScanFileFace_ExistingScan_ReturnByteArray() 
{ 
    //Make testScan 
    List<tblScan> testScan = PrepareTestDataScan(); 

    //Arrange 
    KlantenBL klantenBL = new KlantenBL(); 

    klantenBL.Repository = MockRepository.GenerateMock<IRepository>(); 
    klantenBL.Repository.Stub(bl => bl.GetAll<tblScan>()).IgnoreArguments().Return(testScan); 

    //Act 
    var result = klantenBL.GetScanFileFaceByMemberID(2); 

    //assert 
    Assert.AreEqual(result.GetType().Name, "Byte[]"); 
    Assert.AreEqual(result.Length, 10); 
} 

//Prepare some testData 
private List<tblScan> PrepareTestDataScan() 
{ 
    List<tblScan> scans = new List<tblScan>(); 

    //Declare some variables 
    byte[] byteFile = new byte[4]; 
    byte[] byteFile10 = new byte[10]; 

    DateTime date = new DateTime(2012,01,01); 

    scans.Add(new tblScan { SCANID = 1, MEMBERID = 1, scanFileFace = byteFile, Hair = byteFile, scanFileAvatar = byteFile, scanFileMeasurements = byteFile, scanDate = date }); 
    scans.Add(new tblScan { SCANID = 2, MEMBERID = 2, scanFileFace = byteFile10, Hair = byteFile, scanFileAvatar = byteFile, scanFileMeasurements = byteFile, scanDate = date }); 
    scans.Add(new tblScan { SCANID = 3, MEMBERID = 3, scanFileFace = byteFile, Hair = byteFile, scanFileAvatar = byteFile, scanFileMeasurements = byteFile, scanDate = date }); 

    return scans; 
} 

庫:

public IList<T> GetAll<T>() 
{ 
    DZine_IStyling_ProductionEntities context = GetObjectContext(); 
    IList<T> list = context 
     .CreateQuery<T>(
     "[" + typeof(T).Name + "]") 
     .ToList(); 
    ReleaseObjectContextIfNotReused(); 
    return list; 
} 

public IList<T> GetAll<T>(Func<T, bool> expression) 
{ 
    DZine_IStyling_ProductionEntities context = GetObjectContext(); 
    IList<T> list = context 
     .CreateQuery<T>(
     "[" + typeof(T).Name + "]") 
     .Where(expression) 
     .ToList(); 
    ReleaseObjectContextIfNotReused(); 
    return list; 
} 

這個工作非常感謝大家!

回答

3

從我的角度......

你的邏輯是不能夠直接測試,如果你通過DataBaseEntities上下文(ProductionEntities)與數據庫進行交互。因爲你的邏輯取決於ProductionEntities。

我建議您按照Repository Pattern爲您的數據訪問層。你將能夠讓你的代碼成爲可測性邏輯。該模式將幫助您從邏輯注入數據訪問層。

我也想推薦你遵循依賴注入模式。這種模式將幫助您更輕鬆地對代碼進行單元測試。您將能夠使用模擬框架(如Rhino模擬)來幫助您進行單元測試。

2

這看起來不像一塊業務邏輯和一塊數據訪問一樣多。

可以存根通過一個接口使用依賴注入,是lambda您ProductionEntities以確保您的「使用」以同樣的方式工作:

// Use this in real code 
public class MyClass() : MyClass(() => new ProductionEntities()) 
{ 
} 

// Use this in your test 
public class MyClass(Func<IHaveEntities> entities) 
{ 
    _entities = entitites; 
} 

public byte[] GetScanFileFaceByMemberID(int MemberID) 
{ 
    byte[] scanFileFace; 

    using (IHaveEntities entityContext = _entities()) 
    { 
     scanFileFace = (from scan in entityContext.tblScan 
       where scan.MEMBERID == MemberID 
       select scan.scanFileFace).Single(); 
    } 

    return scanFileFace; 
} 

不過,我認爲這將是矯枉過正。在某些情況下,您確實需要訪問您的數據。 @ pongsathon-keng所說的公平 - 使用存儲庫模式將會有所幫助 - 但我認爲這是屬於的代碼,在存儲庫中。這似乎很簡單,我不會擔心打破對數據的依賴。

您既可以使用集成測試來測試這件作品,也可以測試整個系統,並確保它的這一部分與其他部分搭配良好。

如果您將每個測試看作是如何使用代碼的示例,可能會有所幫助。這不是真的在那裏測試你的代碼,以幫助你探索它應該做什麼,不應該做什麼,以及其他人如何使用它。如果它在集成時使用代碼纔有意義,請編寫集成測試。否則,你可以使用上面的模式注入一個模擬。

相關問題