如何在实体框架中使用"Pex和Moles"库?

Rob*_*nik 15 unit-testing entity-framework pex-and-moles

这是一个艰难的一个,因为没有太多人使用Pex和Moles左右我认为(即使Pex是一个非常好的产品 - 比任何其他单元测试工具好得多)

我有一个Data项目,它有一个非常简单的模型,只有一个实体(DBItem).我还在DBRepository这个项目中写了一个操纵这个EF模型的东西.Repository有一个调用的方法GetItems(),它返回业务层项目列表(BLItem),看起来与此类似(简化示例):

public IList<BLItem> GetItems()
{
    using (var ctx = new EFContext("name=MyWebConfigConnectionName"))
    {
        DateTime limit = DateTime.Today.AddDays(-10);
        IList<DBItem> result = ctx.Items.Where(i => i.Changed > limit).ToList();
        return result.ConvertAll(i => i.ToBusinessObject());
    }
}
Run Code Online (Sandbox Code Playgroud)

所以现在我想为这个特定的方法创建一些单元测试.我正在使用Pex&Moles.我为我的EF对象上下文创建了我的鼹鼠和存根.

我想编写参数化单元测试(我知道我已经编写了我的生产代码,但我必须,因为我正在测试Pex和Moles)测试此方法返回有效的项目列表.

这是我的测试类:

[PexClass]
public class RepoTest
{
    [PexMethod]
    public void GetItemsTest(ObjectSet<DBItem> items)
    {
        MEFContext.ConstructorString = (@this, name) => {
             var mole = new SEFContext();
        };

        DBRepository repo = new DBRepository();
        IList<BLItem> result = repo.GetItems();

        IList<DBItem> manual = items.Where(i => i.Changed > DateTime.Today.AddDays(-10));

        if (result.Count != manual.Count)
        {
            throw new Exception();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我为这个特定的参数化单元测试运行Pex Explorations,但是我得到了超出的错误路径限制.Pex通过提供null此测试方法(so items = null)开始此测试.这是Pex正在运行的代码:

[Test]
[PexGeneratedBy(typeof(RepoTest))]
[Ignore("the test state was: path bounds exceeded")]
public void DBRepository_GetTasks22301()
{
    this.GetItemsTest((ObjectSet<DBItem>)null);
}
Run Code Online (Sandbox Code Playgroud)

这是Pex提供的额外评论:

对于这些输入,测试用例运行时间过长,Pex停止了分析.请注意:方法Oblivious.Data.Test.Repositories.TaskRepositoryTest.b__0被调用了50次; 请检查代码是否没有陷入无限循环或递归.否则,单击"Set MaxStack = 200",然后再次运行Pex.

更新属性[PexMethod(MaxStack = 200)]

我这样做是否正确?我应该使用EFContext存根吗?我是否必须为测试方法添加其他属性,以便Moles主机运行(我现在不确定).我正在运行Pex&Moles.没有VS测试或nUnit或其他任何东西.

我想我应该为Pex设置一些限制它应该为这个特定的测试方法提供多少项.

小智 5

Moles不是为测试具有外部依赖性的应用程序部分而设计的(例如文件访问,网络访问,数据库访问等).相反,Moles允许您模拟应用程序的这些部分,以便您可以对没有外部依赖性的部分进行真正的单元测试.

所以我认为你应该只是模拟你的EF对象和查询,例如,通过创建内存列表并让查询方法根据相关的任何标准从这些列表中返回虚假数据.