如何使用“Pex 和 Moles”带有实体框架的库?

发布于 2024-09-24 02:12:12 字数 2247 浏览 1 评论 0原文

这是一个困难,因为没有太多人使用 Pex 和 Pex。我认为 Moles 左右(尽管 Pex 是一款非常出色的产品 - 比任何其他单元测试工具都要好得多)

我有一个 Data 项目,它有一个非常简单的模型,只有一个实体 (DBItem)。我还在该项目中编写了一个 DBRepository 来操作此 EF 模型。存储库有一个名为 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());
    }
}

所以现在我想为此特定方法创建一些单元测试。我正在使用 Pex &鼹鼠。我为 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();
        }
    }
}

然后我为这个特定的参数化单元测试运行Pex Explorations,但我收到错误超出路径范围。 Pex 通过向此测试方法提供 null 来启动此测试(因此 items = null)。这是 Pex 正在运行的代码:

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

这是 Pex 提供的附加注释:

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

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

问题

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

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

This is a tough one because not too many people use Pex & Moles or so I think (even though Pex is a really great product - much better than any other unit testing tool)

I have a Data project that has a very simple model with just one entity (DBItem). I've also written a DBRepository within this project, that manipulates this EF model. Repository has a method called GetItems() that returns a list of business layer items (BLItem) and looks similar to this (simplified example):

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());
    }
}

So now I'd like to create some unit tests for this particular method. I'm using Pex & Moles. I created my moles and stubs for my EF object context.

I would like to write parametrised unit test (I know I've first written my production code, but I had to, since I'm testing Pex & Moles) that tests that this method returns valid list of items.

This is my test class:

[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();
        }
    }
}

Then I run Pex Explorations for this particular parametrised unit test, but I get an error path bounds exceeded. Pex starts this test by providing null to this test method (so items = null). This is the code, that Pex is running:

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

This was additional comment provided by Pex:

The test case ran too long for these inputs, and Pex stopped the analysis. Please notice: The method Oblivious.Data.Test.Repositories.TaskRepositoryTest.b__0 was called 50 times; please check that the code is not stuck in an infinite loop or recursion. Otherwise, click on 'Set MaxStack=200', and run Pex again.

Update attribute [PexMethod(MaxStack = 200)]

Question

Am I doing this the correct way or not? Should I use EFContext stub instead? Do I have to add additional attributes to test method so Moles host will be running (I'm not sure it does now). I'm running just Pex & Moles. No VS test or nUnit or anything else.

I guess I should probably set some limit to Pex how many items should it provide for this particular test method.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

Moles 并非旨在测试应用程序中具有外部依赖项的部分(例如文件访问、网络访问、数据库访问等)。相反,Moles 允许您模拟应用程序的这些部分,这样您就可以对没有外部依赖项的部分进行真正的单元测试。

因此,我认为您应该模拟您的 EF 对象和查询,例如,通过创建内存列表并让查询方法根据相关的条件从这些列表中返回虚假数据。

Moles is not designed to test the parts of your application that have external dependencies (e.g. file access, network access, database access, etc). Instead, Moles allows you to mock these parts of your app so that way you can do true unit testing on the parts that don't have external dependencies.

So I think you should just mock your EF objects and queries, e.g., by creating in-memory lists and having query methods return fake data from those lists based on whatever criteria is relevant.

那伤。 2024-10-01 02:12:12

我也刚刚开始掌握 pex ...我的问题围绕着我想要将它与最小起订量一起使用;)

无论如何...

我有一些与你类似的方法也有同样的问题。当我增加最大值时,它们就消失了。想必 pex 对它已经充分探索了分支感到满意。我有一些方法,我还必须增加代码合同验证的超时。

您可能应该做的一件事是将所有依赖对象作为参数传递...即不要在方法中实例化存储库,而是将其传入。

您遇到的一个普遍问题是您在方法中实例化大对象。我在 DAL 类中做了同样的事情,但是我不会尝试单独对它们进行单元测试。我构建数据集并使用它来测试我的数据访问代码。

我在业务逻辑和对象上使用 pex。

如果我要尝试测试我的 DAL 代码,则必须使用 IOC 将数据上下文传递到方法中 - 这将使测试成为可能,因为您可以模拟数据上下文。

I am just getting to grips with pex also ... my issues surrounded me wanting to use it with moq ;)

anyway ...

I have some methods similar to your that have the same problem. When i increased the max they went away. Presumably pex was satisfied that it had sufficiently explored the branches. I have methods where i have had to increase the timeout on the code contract validation also.

One thing that you should probably be doign though is passing in all the dependant objects as parameters ... ie dont instantiate the repo in the method but pass it in.

A general problem you have is that you are instantiating big objects in your method. I do the same in my DAL classes, but then i am not tryign to unit test them in isolation. I build up datasets and use this to test my data access code against.

I use pex on my business logic and objects.

If i were to try and test my DAL code id have to use IOC to pass the datacontext into the methods - which would then make testing possible as you can mock the data context.

奶茶白久 2024-10-01 02:12:12

您应该使用实体框架存储库模式: http://www.codeproject.com/KB/database /ImplRepositoryPatternEF.aspx

You should use Entity Framework Repository Pattern: http://www.codeproject.com/KB/database/ImplRepositoryPatternEF.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文