每周源代码58-用AutoPoco和Entity Framework Code First生成(数据库)测试数据

[原文发表地址] The Weekly Source Code 58 - Generating (Database) Test Data with AutoPoco and Entity Framework Code First

[原文发表时间] 2011-01-05 12:40

 

我最近在为实体框架代码优先(Entity Framework Code First,我喜欢将之称为EF 神奇的独角兽)的数据访问而烦恼,并且需要很多测试数据。这样的苦差事。完全没有乐趣。我总是在敲打完键盘后这么想:应该是由别人来敲打键盘的。同属一个类别的10个例子的测试数据很容易,但是1000个就不是那么的鼓舞人心了。

 

当然,有许多软件我可以购买来用于解决像那样的问题,但是…。我四处搜寻了一下,从Rob Ashton(@robashton)发现了一个叫做AutoPoco的开源框架。首先,这是一个很棒的名字。我喜欢使用名字很酷的开源项目。这就像喜欢阅读一本有着精美封面的图书一样。这会使你很想投入进去。接着,我就开始使用它进行工作并且意识到在这个相当小的库里有些不错的东西。如果更多就更好了,对吧?

 

AutoPoco的CodePlex项目说:

AutoPoco是一个可配置性很高的框架,是用来从Plain Old CLR Objects里流畅地创建可读的测试数据的。

 

这是总体思路。你需要100个(或者5个,或任何其他数量)某种东西达到一种特定的方式,因此你让AutoPoco为你创建一堆,就是这样。就是那么地简单。

 

例如,请给我SimpleUser类型的1000个对象并设置它们的FirstName为"Bob.":

 

IList<SimpleUser> users = session.List<SimpleUser>(1000).Impose(x => x.FirstName, "Bob").

 

尽管如此,此处才是它真正的亮点:

 

session.List<SimpleUser>(100)

                 .First(50)

                      .Impose(x => x.FirstName, "Rob")

                      .Impose(x => x.LastName, "Ashton")

                  .Next(50)

                      .Impose(x => x.FirstName, "Luke")

                      .Impose(x => x.LastName, "Smith")

                  .All().Random(25)

                      .Impose(x => x.Role,roleOne)

                  .Next(25)

                      .Impose(x => x.Role,roleTwo)

                  .Next(50)

                      .Impose(x => x.Role, roleThree)

                 .All()

                      .Invoke(x => x.SetPassword("Password1"))

                 .Get();

 

这是说:创造100个用户前50个用户会被叫做Rob Ashton后50个会被叫做Luke Smith25个随机用户将属于RoleOne(角色一)另外25个随机用户将属于RoleTwo(角色二)剩下的50个用户将属于RoleThree (角色三)并把每一个单个用户的密码设置成Password1

实际上,它是无极限的。你也可以给AutoPoco更为先进的要求像“使电子邮件符合这些要求”,或者“当需要获得一个密码时调用此方法”。其用意不仅仅是为了获得测试数据,而是要获得一定程度上有意义的测试数据。

 

这使我想到:既然我们正在使用POCOs (Plain Ol' CLR Objects),那么不仅在单元测试并且在集成测试和冒烟测试中我都可以使用这个。我可以使用这个在数据库中生成测试数据。最好在使用POCOs的新的实体框架代码中也使用这个。

 

例如:

 

public void MakeTestData()

{

    IGenerationSessionFactory factory = AutoPocoContainer.Configure(x =>

    {

        x.Conventions(c => { c.UseDefaultConventions(); });

        x.AddFromAssemblyContainingType<SimpleUser>();

    });

 

    IGenerationSession session = factory.CreateSession();

 

    IList<SimpleUser> users = session.List<SimpleUser>(1000)

        .First(500)

            .Impose(x => x.FirstName, "Bob")

        .Next(500)

            .Impose(x => x.FirstName, "Alice")

        .All()

            .Impose(x => x.LastName, "Hanselman")

        .Random(250)

            .Impose(x => x.LastName, "Blue")

        .All().Random(400)

            .Impose(x => x.LastName, "Red")

        .All()

        .Get();

 

    SimpleUserDatabase db = new SimpleUserDatabase();

    foreach (SimpleUser s in users)

    {

        db.Users.Add(s);

    }

    db.SaveChanges();

}

 

很迅速地,在我的小数据库里我已经有了1000个用户。

 

我和作者Rob谈过了,我认为会话的创建和 Factory stuff 可以被做的更小一些,并且底部的循环可以减少一两行。Rob是一个很务实的人,我期待着AutoPoco接下来的发展!总之,这是多么有用的一个库啊!我甚至可以看到自己会很多地使用它。

 

你可以从CodePlex来获得AutoPoco或者更佳的是,可以通过 " install-package autopoco "使用NuGet ( https://nuget.org )从Visual Studio里面来获得。

享受这些吧!这个库有36个下载,但是它值得更多的一些数量级的订单。我会尽我所能来展示更多的值得我们进一步关注的开源库(更重要的是,它们要能被用上)。如果你有非常有用的库要推荐,请随时给我发电子邮件。