2

Given that most real world applications have fairly complicated relationships between entities, is there much value in testing individual class mappings? It seems that to be truly valuable, NHibernate tests should revolve around retrieving, persisting and deleting entire object graphs, starting at the aggregate root level (i.e. Customer-->Order-->OrderDetails). But if I go down that road, it seems I would have to test CRUD operations at every conceivable level in the object tree to validate that the "whole" works as expected; leading to an explosion of tests:

  • Delete a Customer
  • Delete an Order
  • Delete an OrderItem
  • Insert a Customer
  • Insert an Order
  • Insert an OrderItem

So, unless I'm missing something, which I very likely am, my choices are:

  1. Write one fixture suite per class/mapping
    • Pros: Simpler to write CRUD operations
    • Cons: Diminished test value, as they provide no assurance that entire aggregate roots are being persisted correctly
  2. Write one fixture suite per object graph
    • Cons: Tests harder to write/explosion of test scenarios
    • Pros: Higher value as tests since they test persistence from the application's perspective (i.e. testing mutations against the unified/integrated object graph)

If at all relevant, I'm using the NHibernate.Mapping.ByCode ConventionModelMapper to generate mappings using conventions.

4

1 回答 1

1

是的,当测试我的映射是否按预期工作时,我在类级别进行测试并测试每个单独的类关系。

例如,如果我有一个包含 Order 对象列表的 Customer 对象,我将为我的 Customer 对象编写集成测试,以确保我可以对该对象执行所有 CRUD 操作。然后,我将为 Customer 对象所具有的所有关系编写测试,例如具有订单、地址等列表。这些测试将涵盖诸如级联插入/更新/删除之类的内容,以及急切获取这些子集合的能力一个问题。

因此,尽管我在类级别进行测试,因为我正在测试每个类的所有关系,但我在技术上测试整个对象图,只要我在我的每个测试中继续这种测试行为映射类。

更新(添加简要示例):

public class Customer
{
    public int CustomerId { get; set; }
    public string CompanyName { get; set; }
    public IList<Address> Addresses { get; set; }
    public IList<Order> Orders { get; set; }
}

public class Address
{
    public int AddressId { get; set; }
}

public class Order
{
    public int OrderId { get; set; }
    public string Status { get; set; }
    public IList<OrderDetail> OrderDetails { get; set; }
}

public class OrderDetail
{
    public int OrderDetailId { get; set; }
    public string City { get; set; }
}

[TestFixture]
public class CustomerMappingTests
{
    private ISession session;

    [SetUp]
    public void SetUp()
    {
        session = UnitOfWork.Current.GetSession();
    }

    [TearDown]
    public void TearDown()
    {
        session.Dispose();
    }

    [Test]
    public void CanGetCustomer()
    {
        // Arrange
        const int customerId = 1;

        // Act
        var customer = session.Query<Customer>()
            .Where( x => x.CustomerId == customerId )
            .FirstOrDefault();

        // Assert
        Assert.NotNull( customer );
        Assert.That( customer.CustomerId == customerId );
    }

    [Test]
    public void CanGetCustomerAddresses()
    {
        // Arrange
        const int customerId = 1;

        // Act
        var customer = session.Query<Customer>()
            .Where( x => x.CustomerId == customerId )
            .Fetch( x => x.Addresses )
            .FirstOrDefault();

        // Assert
        Assert.NotNull( customer.Addresses.Count > 0 );
    }

    [Test]
    public void CanGetCustomerOrders()
    {
        // Arrange
        const int customerId = 1;

        // Act
        var customer = session.Query<Customer>()
            .Where( x => x.CustomerId == customerId )
            .Fetch( x => x.Orders )
            .FirstOrDefault();

        // Assert
        Assert.NotNull( customer.Orders.Count > 0 );
    }

    [Test]
    public void CanSaveCustomer()
    {
        // Arrange
        const string companyName = "SnapShot Corporation";
        var customer = new Customer { CompanyName = companyName };

        // Act
        session.Save( customer );

        session.Flush(); // Update the database right away
        session.Clear(); // Clear cache

        var customer2 = session.Query<Customer>()
            .Where( x => x.CompanyName == companyName )
            .FirstOrDefault();

        // Assert
        Assert.NotNull( customer2 );
        Assert.That( customer2.CompanyName == companyName );
    }
}
于 2012-11-14T22:10:41.320 回答