开发者

How to use "Pex and Moles" library with Entity Framework?

开发者 https://www.devze.com 2023-01-17 14:26 出处:网络
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)

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.

开发者_StackOverflow社区

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.


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.


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.


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

0

精彩评论

暂无评论...
验证码 换一张
取 消