DAL和BLL的单元/集成测试(使用lambdas)

时间:2015-08-14 15:27:05

标签: c# unit-testing mocking integration-testing data-access-layer

我的代码基本上是这样的:

数据访问合同:

public interface IProvideDataAccess<T>
    where T : Entity
{
    IEnumerable<T> Select(Func<T, bool> condition);
    void Save(T entity);
    void Delete(T entity);
}

数据访问层:

public class Db4oProvider<T> : IProvideDataAccess<T>
    where T : Entity
{
    private IEmbeddedConfiguration _configuration;
    private string _connectionString;

    public Db4oAccesDonnees(string connectionString)
    {
        _connectionString = connectionString;
        _configuration = Db4oEmbedded.NewConfiguration();
    }

    IEnumerable<T> IProvideDataAccess<T>.Select(Func<T, bool> condition)
    {
        using (IObjectContainer db = Db4oEmbedded.OpenFile(_configuration, _connexion))
        {
            return db.Query<T>(e => condition(e));
        }
    }
    void IProvideDataAccess<T>.Save(T entity)
    {
        using (IObjectContainer db = Db4oEmbedded.OpenFile(_configuration, _connexion))
        {
            db.Store(entity);
        }
    }
    void IProvideDataAccess<T>.Delete(T entity)
    {
        using (IObjectContainer db = Db4oEmbedded.OpenFile(_configuration, _connexion))
        {
            db.Delete(entity);
        }
    }
}

业务逻辑层:

public class MyRepository
{
    protected IProvideDataAccess<MyEntityType> _dataAccessProvider;

    public MyRepository(IProvideDataAccess<MyEntityType> dataAccessProvider)
    {
        _dataAccessProvider = dataAccessProvider;
    }

    public IEnumerable<MyEntityType> SelectValidEntities()
    {
        return _dataAccessProvider.Select(e => /* test if entity is valid */);
    }
}

单元/集成测试对我来说相当新,我不知道从哪里开始。

认为要做的合乎逻辑的事情是

  • 为DAL编写集成测试
  • 为BLL编写单元测试(使用假DAL)

我这是对的吗?

我最大的问题是“select”方法及其Func参数。我该如何测试/模拟它?

基本上,我应该为这两个类写什么测试?

1 个答案:

答案 0 :(得分:0)

您的DAL看起来像是永不改变的类......在我看来,在它们上创建UTIT是浪费时间。您应该使用良好的Component /&#34; large Integration&#34;(不仅仅是单元+ DB)测试来覆盖类Db4oProvider<T>之类的行为。我建议您阅读Test PyramidIn Martin Fowler blogthis good article)。我喜欢以下金字塔:

enter image description here

关于Select方法:

Integration test(单位+数据库)中,您必须将数据放入数据库中(或保留带有数据的数据库......),请使用条件调用Select,然后验证您是否为&#39我们得到了预期的数据。

Component test中,您需要将其作为测试行为的一部分进行测试,如果测试成功,那么每件事情都可以......

UT中,测试分为两种类型:

1.您验证传递到Select方法的条件(lambda)行为的测试:(这样您还可以验证使用正确的参数调用Select ...在我的示例中,我使用RhinoMocks

var fakeProvider = MockRepository.GenerateStub<IProvideDataAccess<Entity>>();

fakeProvider.Select(o => o.Id =="asdfg");

fakeProvider.AssertWasCalled(access => access.Select(Arg<Func<Entity, bool>>
            .Matches(func => func(new Entity()
            {
                Id = "asdfg"
            }))));

2.验证调用方法行为的测试。在这些测试中,您应该配置DAL以返回参数的重要内容:

_selectResult = new List<Entity>();
fakeProvider.Stub(x => x.Select(Arg<Func<Entity, bool>>.Is.Anything))
            .Return(_selectResult);