1

I use the Microsoft Entity Framework and have some nested entities

GrandParent, Parent, Child

In a C# test I would like to be able to read an array of GrandParents including their descendants from an xml file, e.g. (fake code example:)

[TestMethod]
[DataSource("myTestData.xml")] 
public void MyTest(){
       List<GrandParent> grandParents = TestContext.GetEntityList(GrandParent.class);
}

<?xml version="1.0" encoding="utf-8" ?>
<TestData>
<GrandParent>
  <name>GrandParent_1</name>
  <Parent>
    <name>Parent_1.1</name>
    <Child>
      <name>Child_1.1.1</name>         
    </Child>
  </Parent>
</GrandParent>

<GrandParent>
  <name>GrandParent_2</name>
  <Parent>
    <name>Parent_2.1</name>
    <Child>
      <name>Child_2.1.1</name>         
    </Child>
  </Parent>
  <Parent>
    <name>Parent_2.2</name>
    <Child>
      <name>Child_2.2.1</name>         
    </Child>
  </Parent>
</GrandParent>
<TestData>

The above syntax is not supported by the DataSource annotation and I could only find examples for reading flat data from the DataSource. https://msdn.microsoft.com/en-us/library/ms182527.aspx

Reading hierarchical data and converting that data to an entity object tree does not seem to be supported.

Is there an easy way to create an entity object tree from an xml DataSource for the purpose of testing? Maybe something like Unitils (http://unitils.org/tutorial-database.html) in Java, but for .Net? Ideally, the xml file does not need to include all attributes of the entities: only those entity attributes that are used in the test need to be specified.

Related questions

Community
  • 1
  • 1
Stefan
  • 10,010
  • 7
  • 61
  • 117

3 Answers3

0

Can you use an XmlSerializer and serialize your entities for later de-serlialization?

https://msdn.microsoft.com/en-us/library/58a18dwa(v=vs.110).aspx

Gary McGill
  • 26,400
  • 25
  • 118
  • 202
  • That might be a way to go. I hoped that there already exists a testing library that supports "the import of mocks from (incomplete) xml test data". – Stefan Dec 10 '15 at 16:29
0

I found Effort - Entity Framework Unit Testing Tool, that does not seem to support xml but at least allows to read csv data to populate an in memory test database:

https://effort.codeplex.com/wikipage?title=Startup%20data%20from%20CSV%20files&referringTitle=Tutorials

Stefan
  • 10,010
  • 7
  • 61
  • 117
0

You mentioned CSV as a possible option, so I will mention I created a T4 template that reads CSV files and generates lists of data, mainly for use in unit tests. You would have to handle the object hierarchy yourself, so this may not be suitable for your needs. But... you could have a test like this (only populating one level of descendants for illustration):

[TestMethod]
public void TestMethod1()
{
    StaticDataLibrary library = StaticDataLibrary.Current;
    var people = library.GetList<Person>("people.csv");
    var grandparents = people
        .Where(p => p.ParentId == null)
        .Select(gp => new GrandParent()
        {
            Id = gp.Id,
            Name = gp.Name,
            Children = people
                .Where(c => c.ParentId == gp.Id)
                .Select(c => new Person()
                {
                    Id = c.Id,
                    Name = c.Name
                }).ToList()

        })
        .ToList();

    Mock<IDataAccess> dataAccess = new Mock<IDataAccess>();
    dataAccess.Setup(m => m.GetGrandParents())
        .Returns(grandparents);

    // invoke the method that uses the data and make assertions...
}

The list would be generated from a CSV file (comments are OK too), such as:

Id, ParentId, Name
// Grand Parents
"1", null, "GrandParent_1"
"2", null, "GrandParent_2"

// Parents
"1.1", "1", "Parent_1.1"
"2.1", "2", "Parent_2.1"
"2.2", "2", "Parent_2.2"

// Grand Children
"1.1.1", "1.1", "Child_1.1.1"
"2.1.1", "2.1", "Child_2.1.1"
"2.2.1", "2.2", "Child_2.2.1"

The CSV file is not read during the test execution. The T4 template creates the StaticDataLibrary at design-time, which is intentional to avoid file system access during the test execution.

I created a NuGet package that installs the template (VB or C#) into your project if you are interested.

Dominick
  • 323
  • 3
  • 11