如何为此业务逻辑代码编写可靠的单元测试?

dg9*_*g90 5 c# unit-testing

我得到了一些我想测试的业务逻辑代码.
目前我只知道如何在没有其他依赖关系的逻辑代码上编写单元测试.

任何人都可以指出我如何测试这个功能的好方向,也许举个例子?

是测试这个集成测试的唯一方法还是我必须使用mock/stub?

/// <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;
}
Run Code Online (Sandbox Code Playgroud)

CHANGES(我实现了Repository&rhino mocks):

BL:

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

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

    scanFileFace = query.scanFileFace;

    return scanFileFace;
}
Run Code Online (Sandbox Code Playgroud)

单元测试:

[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;
}
Run Code Online (Sandbox Code Playgroud)

库:

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;
}
Run Code Online (Sandbox Code Playgroud)

这完全归功于所有人!

Pon*_*eng 3

依我看来...

您的逻辑无法测试您是否直接通过 DataBaseEntities context(ProductionEntities) 与数据库交互。因为你的逻辑依赖于 ProductionEntities。

我建议您 为数据访问层遵循存储库模式。您将能够使代码成为可测试性逻辑。该模式将帮助您从逻辑注入数据访问层。

我还想建议您遵循依赖注入模式。此模式将帮助您更轻松地对代码进行单元测试。您将能够使用像Rhino模拟这样的模拟框架来帮助您进行单元测试。