{"id":24,"date":"2008-06-20T10:30:07","date_gmt":"2008-06-20T16:30:07","guid":{"rendered":"https:\/\/www.chrisedwards.dreamhosters.com\/blog\/2008\/06\/20\/testing-nhibernate-mappings\/"},"modified":"2010-06-14T22:54:25","modified_gmt":"2010-06-15T04:54:25","slug":"testing-nhibernate-mappings","status":"publish","type":"post","link":"http:\/\/architester.com\/blog\/2008\/06\/20\/testing-nhibernate-mappings\/","title":{"rendered":"Testing NHibernate Mappings"},"content":{"rendered":"<p>Several posts have been made lately concerning testing NHibernate Mappings. I thought I would share what I have done for the past few months.<\/p>\n<p>I create a test fixture for each class mapped in NHibernate. The tests in the fixture test loading, updating, saving, and deleting through NHibernate.<\/p>\n<p>Initially, I only tested loading, but later found out that when we started saving objects with NHibernate, it broke. Likewise, with deletes, I found some cascading deletes conflicted with triggers in the database (that I had no conrtol over). Had I tested the deletion, I would have known. So I find it a good practice to test all of the above for your mappings.<\/p>\n<p>Here are some sample tests<\/p>\n<p><!--\n{\\rtf1\\ansi\\ansicpg\\lang1024\\noproof1252\\uc1 \\deff0{\\fonttbl{\\f0\\fnil\\fcharset0\\fprq1 Tahoma;}}{\\colortbl;??\\red0\\green0\\blue0;\\red255\\green255\\blue255;\\red0\\green0\\blue128;\\red0\\green0\\blue255;\\red0\\green128\\blue0;}??\\fs16 \\par ??    [ \\cf3 TestMethod\\cf0  ]\\par ??    \\cf4 public\\cf0  \\cf4 void\\cf0  Loading_a_VirtualColumn_will_populate_all_its_properties()\\par ??    \\{\\par ??      \\cf3 VirtualColumn\\cf0  expectedColumn = \\cf3 Anonymous\\cf0 .VirtualColumn();\\par ??\\par ??      \\cf5 \/\/ Insert column into Db.\\par ??\\cf0       _context.AddVirtualColumn( expectedColumn );\\par ??      _context.Persist( _session );\\par ??\\par ??      \\cf5 \/\/ Load from Db.\\par ??\\cf0       \\cf3 VirtualColumn\\cf0  actualColumn = _session.Get&lt;\\cf3 VirtualColumn\\cf0 &gt;( expectedColumn.Id );\\par ??\\par ??      \\cf5 \/\/ Ensure all properties match.\\par ??\\cf0       \\cf3 TestAssertions\\cf0 .VirtualColumnEquals( expectedColumn, actualColumn );\\par ??    \\}\\par ??\\par ??\\par ??    [ \\cf3 TestMethod\\cf0  ]\\par ??    \\cf4 public\\cf0  \\cf4 void\\cf0  Should_be_able_to_retrieve_a_list_of_all_virtual_columns()\\par ??    \\{\\par ??      \\cf3 VirtualColumn\\cf0  expectedColumn1 = \\cf3 Anonymous\\cf0 .VirtualColumn();\\par ??      \\cf3 VirtualColumn\\cf0  expectedColumn2 = \\cf3 Anonymous\\cf0 .VirtualColumn();\\par ??\\par ??      _context.AddVirtualColumn( expectedColumn1 );\\par ??      _context.AddVirtualColumn( expectedColumn2 );\\par ??      _context.Persist( _session );\\par ??\\par ??      \\cf3 List\\cf0 &lt;\\cf3 VirtualColumn\\cf0 &gt; columns = _repository.FindVirtualColumns();\\par ??\\par ??      \\cf3 TestAssertions\\cf0 .ListContainsVirtualColumns( columns, expectedColumn1, expectedColumn2 );\\par ??    \\}\\par ??\\par ??\\par ??    [ \\cf3 TestMethod\\cf0  ]\\par ??    \\cf4 public\\cf0  \\cf4 void\\cf0  Updating_a_VirtualColumns_CriteriaExpression_and_saving_should_persist_the_change()\\par ??    \\{\\par ??      \\cf3 VirtualColumn\\cf0  column = \\cf3 Anonymous\\cf0 .VirtualColumn_WithVersionCriteria();\\par ??\\par ??      \\cf5 \/\/ Insert column with its criteria expression into Db.\\par ??\\cf0       _context.AddVirtualColumn( column );\\par ??      _context.Persist( _session );\\par ??\\par ??      \\cf5 \/\/ Get column to update from db.\\par ??\\cf0       \\cf3 VirtualColumn\\cf0  persistedColumn = _session.Get&lt;\\cf3 VirtualColumn\\cf0 &gt;( column.Id );\\par ??      \\cf3 Assert\\cf0 .IsInstanceOfType( persistedColumn.CriteriaExpression, \\cf4 typeof\\cf0  ( \\cf3 VersionExpression\\cf0  ) );\\par ??\\par ??      \\cf5 \/\/ Update column and persist.\\par ??\\cf0       persistedColumn.CriteriaExpression = \\cf3 Anonymous\\cf0 .BudgetYearExpression();\\par ??      _session.SaveOrUpdate( persistedColumn );\\par ??      _session.Flush();\\par ??\\par ??      \\cf5 \/\/ Get the updated column.\\par ??\\cf0       \\cf3 VirtualColumn\\cf0  actualColumn = _session.Get&lt;\\cf3 VirtualColumn\\cf0 &gt;( column.Id );\\par ??\\par ??      \\cf5 \/\/ Ensure the change was persisted.\\par ??\\cf0       \\cf3 Assert\\cf0 .IsInstanceOfType( actualColumn.CriteriaExpression, \\cf4 typeof\\cf0  ( \\cf3 BudgetYearExpression\\cf0  ) );\\par ??    \\}\\par ??\\par ??\\par ??    [ \\cf3 TestMethod\\cf0  ]\\par ??    \\cf4 public\\cf0  \\cf4 void\\cf0  Updating_a_VirtualColumns_CalculationExpression_and_saving_should_persist_the_change()\\par ??    \\{\\par ??      \\cf3 VirtualColumn\\cf0  childColumn1 = \\cf3 Anonymous\\cf0 .VirtualColumn();\\par ??      \\cf3 VirtualColumn\\cf0  childColumn2 = \\cf3 Anonymous\\cf0 .VirtualColumn();\\par ??      \\cf3 VirtualColumn\\cf0  calculatedColumn = \\cf3 Anonymous\\cf0 .VirtualColumn_Adding( childColumn1, childColumn2 );\\par ??\\par ??      \\cf5 \/\/ Insert column into Db.\\par ??\\cf0       _context.AddVirtualColumn( childColumn1 )\\par ??        .AddVirtualColumn( childColumn2 )\\par ??        .AddVirtualColumn( calculatedColumn );\\par ??      _context.Persist( _session );\\par ??\\par ??      \\cf3 VirtualColumn\\cf0  persistedColumn = _repository.Find( calculatedColumn.Id );\\par ??\\par ??      persistedColumn.CalculationExpression =\\par ??        \\cf3 Anonymous\\cf0 .RemoveUniqueId(\\par ??          \\cf3 Anonymous\\cf0 .SubtractExpression(\\par ??            \\cf3 Anonymous\\cf0 .VirtualColumnExpression( childColumn1 ),\\par ??            \\cf3 Anonymous\\cf0 .VirtualColumnExpression( childColumn2 )\\par ??            ) );\\par ??\\par ??\\par ??      _session.Clear();\\par ??      _repository.Save( persistedColumn );\\par ??\\par ??      _session.Clear();\\par ??      \\cf3 VirtualColumn\\cf0  actualColumn = _repository.Find( calculatedColumn.Id );\\par ??\\par ??      \\cf3 Assert\\cf0 .IsInstanceOfType( actualColumn.CalculationExpression, \\cf4 typeof\\cf0  ( \\cf3 SubtractExpression\\cf0  ) );\\par ??    \\}\\par ??\\par ??\\par ??    [ \\cf3 TestMethod\\cf0  ]\\par ??    \\cf4 public\\cf0  \\cf4 void\\cf0  Deleting_a_Virtual_Column_should_remove_it_from_the_db()\\par ??    \\{\\par ??      \\cf3 VirtualColumn\\cf0  column = \\cf3 Anonymous\\cf0 .VirtualColumn();\\par ??\\par ??      \\cf5 \/\/ Insert column into Db.\\par ??\\cf0       _context.AddVirtualColumn( column );\\par ??      _context.Persist( _session );\\par ??\\par ??      \\cf5 \/\/ Get column to delete from db.\\par ??\\cf0       \\cf3 VirtualColumn\\cf0  persistedColumn = _session.Get&lt;\\cf3 VirtualColumn\\cf0 &gt;( column.Id );\\par ??\\par ??      \\cf5 \/\/ Delete the column.\\par ??\\cf0       _session.Delete( persistedColumn );\\par ??      _session.Flush();\\par ??\\par ??      \\cf5 \/\/ Ensure it was removed from db.\\par ??\\cf0       \\cf3 TestDataAssertions\\cf0 .VirtualColumnDoesNotExist( column, _session );\\par ??    \\}\\par ??\\par ??\\par ??    [ \\cf3 TestMethod\\cf0  ]\\par ??    \\cf4 public\\cf0  \\cf4 void\\cf0  Deleting_a_Virtual_Column_should_also_remove_its_Criteria_Expression_from_the_db()\\par ??    \\{\\par ??      \\cf3 VirtualColumn\\cf0  column = \\cf3 Anonymous\\cf0 .VirtualColumn_ForAmountInPeriod( January );\\par ??\\par ??      \\cf5 \/\/ Insert column into Db.\\par ??\\cf0       _context.AddVirtualColumn( column );\\par ??      _context.Persist( _session );\\par ??\\par ??      \\cf5 \/\/ Get column to delete from db.\\par ??\\cf0       \\cf3 VirtualColumn\\cf0  persistedColumn = _session.Get&lt;\\cf3 VirtualColumn\\cf0 &gt;( column.Id );\\par ??\\par ??      \\cf5 \/\/ Delete the column.\\par ??\\cf0       _session.Delete( persistedColumn );\\par ??      _session.Flush();\\par ??\\par ??      \\cf5 \/\/ Ensure it was removed from db.\\par ??\\cf0       \\cf3 TestDataAssertions\\cf0 .ExpressionDoesNotExist( column.CriteriaExpression, _session );\\par ??    \\}\\par ??}\n--><\/p>\n<div style=\"font-size: 9pt; background: white; color: black; font-family: tahoma;\">\n<p style=\"margin: 0px;\">[ <span style=\"color: navy;\">TestMethod<\/span> ]<\/p>\n<p style=\"margin: 0px;\"><span style=\"color: blue;\">public<\/span> <span style=\"color: blue;\">void<\/span> Loading_a_VirtualColumn_will_populate_all_its_properties()<\/p>\n<p style=\"margin: 0px;\">{<\/p>\n<p style=\"margin: 0px;\"><span style=\"color: navy;\">VirtualColumn<\/span> expectedColumn = <span style=\"color: navy;\">Anonymous<\/span>.VirtualColumn();<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Insert column into Db.<\/span><\/p>\n<p style=\"margin: 0px;\">_context.AddVirtualColumn( expectedColumn );<\/p>\n<p style=\"margin: 0px;\">_context.Persist( _session );<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Load from Db.<\/span><\/p>\n<p style=\"margin: 0px;\"><span style=\"color: navy;\">VirtualColumn<\/span> actualColumn = _session.Get&lt;<span style=\"color: navy;\">VirtualColumn<\/span>&gt;( expectedColumn.Id );<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Ensure all properties match.<\/span><\/p>\n<p style=\"margin: 0px;\"><span style=\"color: navy;\">TestAssertions<\/span>.VirtualColumnEquals( expectedColumn, actualColumn );<\/p>\n<p style=\"margin: 0px;\">}<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\">[ <span style=\"color: navy;\">TestMethod<\/span> ]<\/p>\n<p style=\"margin: 0px;\"><span style=\"color: blue;\">public<\/span> <span style=\"color: blue;\">void<\/span> Updating_a_VirtualColumns_CriteriaExpression_and_saving_should_persist_the_change()<\/p>\n<p style=\"margin: 0px;\">{<\/p>\n<p style=\"margin: 0px;\"><span style=\"color: navy;\">VirtualColumn<\/span> column = <span style=\"color: navy;\">Anonymous<\/span>.VirtualColumn_WithVersionCriteria();<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Insert column with its criteria expression into Db.<\/span><\/p>\n<p style=\"margin: 0px;\">_context.AddVirtualColumn( column );<\/p>\n<p style=\"margin: 0px;\">_context.Persist( _session );<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Get column to update from db.<\/span><\/p>\n<p style=\"margin: 0px;\"><span style=\"color: navy;\">VirtualColumn<\/span> persistedColumn = _session.Get&lt;<span style=\"color: navy;\">VirtualColumn<\/span>&gt;( column.Id );<\/p>\n<p style=\"margin: 0px;\"><span style=\"color: navy;\">Assert<\/span>.IsInstanceOfType( persistedColumn.CriteriaExpression,<\/p>\n<p style=\"margin: 0px;\"><span style=\"color: blue;\">typeof<\/span> ( <span style=\"color: navy;\">VersionExpression<\/span> ) );<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Update column and persist.<\/span><\/p>\n<p style=\"margin: 0px;\">persistedColumn.CriteriaExpression = <span style=\"color: navy;\">Anonymous<\/span>.BudgetYearExpression();<\/p>\n<p style=\"margin: 0px;\">_session.SaveOrUpdate( persistedColumn );<\/p>\n<p style=\"margin: 0px;\">_session.Flush();<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Get the updated column.<\/span><\/p>\n<p style=\"margin: 0px;\"><span style=\"color: navy;\">VirtualColumn<\/span> actualColumn = _session.Get&lt;<span style=\"color: navy;\">VirtualColumn<\/span>&gt;( column.Id );<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Ensure the change was persisted.<\/span><\/p>\n<p style=\"margin: 0px;\"><span style=\"color: navy;\">Assert<\/span>.IsInstanceOfType( actualColumn.CriteriaExpression,<\/p>\n<p style=\"margin: 0px;\"><span style=\"color: blue;\"> typeof<\/span> ( <span style=\"color: navy;\">BudgetYearExpression<\/span> ) );<\/p>\n<p style=\"margin: 0px;\">}<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\">[ <span style=\"color: navy;\">TestMethod<\/span> ]<\/p>\n<p style=\"margin: 0px;\"><span style=\"color: blue;\">public<\/span> <span style=\"color: blue;\">void<\/span> Deleting_a_Virtual_Column_should_remove_it_from_the_db()<\/p>\n<p style=\"margin: 0px;\">{<\/p>\n<p style=\"margin: 0px;\"><span style=\"color: navy;\">VirtualColumn<\/span> column = <span style=\"color: navy;\">Anonymous<\/span>.VirtualColumn();<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Insert column into Db.<\/span><\/p>\n<p style=\"margin: 0px;\">_context.AddVirtualColumn( column );<\/p>\n<p style=\"margin: 0px;\">_context.Persist( _session );<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Get column to delete from db.<\/span><\/p>\n<p style=\"margin: 0px;\"><span style=\"color: navy;\">VirtualColumn<\/span> persistedColumn = _session.Get&lt;<span style=\"color: navy;\">VirtualColumn<\/span>&gt;( column.Id );<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Delete the column.<\/span><\/p>\n<p style=\"margin: 0px;\">_session.Delete( persistedColumn );<\/p>\n<p style=\"margin: 0px;\">_session.Flush();<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Ensure it was removed from db.<\/span><\/p>\n<p style=\"margin: 0px;\"><span style=\"color: navy;\">TestDataAssertions<\/span>.VirtualColumnDoesNotExist( column, _session );<\/p>\n<p style=\"margin: 0px;\">}<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\">[ <span style=\"color: navy;\">TestMethod<\/span> ]<\/p>\n<p style=\"margin: 0px;\"><span style=\"color: blue;\">public<\/span> <span style=\"color: blue;\">void<\/span> Deleting_a_Virtual_Column_should_also_remove_its_Criteria_Expression_from_the_db()<\/p>\n<p style=\"margin: 0px;\">{<\/p>\n<p style=\"margin: 0px;\"><span style=\"color: navy;\">VirtualColumn<\/span> column = <span style=\"color: navy;\">Anonymous<\/span>.VirtualColumn_ForAmountInPeriod( January );<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Insert column into Db.<\/span><\/p>\n<p style=\"margin: 0px;\">_context.AddVirtualColumn( column );<\/p>\n<p style=\"margin: 0px;\">_context.Persist( _session );<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Get column to delete from db.<\/span><\/p>\n<p style=\"margin: 0px;\"><span style=\"color: navy;\">VirtualColumn<\/span> persistedColumn = _session.Get&lt;<span style=\"color: navy;\">VirtualColumn<\/span>&gt;( column.Id );<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Delete the column.<\/span><\/p>\n<p style=\"margin: 0px;\">_session.Delete( persistedColumn );<\/p>\n<p style=\"margin: 0px;\">_session.Flush();<\/p>\n<p style=\"margin: 0px;\">\n<p style=\"margin: 0px;\"><span style=\"color: green;\">\/\/ Ensure it was removed from db.<\/span><\/p>\n<p style=\"margin: 0px;\"><span style=\"color: navy;\">TestDataAssertions<\/span>.ExpressionDoesNotExist( column.CriteriaExpression, _session );<\/p>\n<p style=\"margin: 0px;\">}<\/p>\n<\/div>\n<p>The code may require some explanation, because much of the nuts and bolts functionality is hidden behind classes that make the tests much more readable. Let me explain what these do:<\/p>\n<p>The <strong>_context<\/strong> object is a DynamicConext class that I created for unit testing that allows me to easily create test object graphs, and it also provides the ability to insert the data from those objects into a database. It uses the NHibernate _session object to do so, but doesn\u00e2\u20ac\u2122t use the NHibernate mappings.<\/p>\n<p>The <strong>Anonymous<\/strong> object is an object mother I created to create anonymous test objects. It simply returns a valid object with random data.<\/p>\n<p>The <strong>TestAssertions<\/strong> and <strong>TestDataAssertions<\/strong> classes are custom assertions I wrote to increase readability of the tests. The TestAssertions assert against objects whereas the TestDataAssertions assert against a database. This is so that I can test the database state independently from NHibernate. (It\u00e2\u20ac\u2122s not a good idea to use NHibernate to test NHibernate).<\/p>\n<p>Note that the tests do not use any custom repositories from my domain. They just use the NHibernate session directly. This is because I am not testing my repositories. I only want to test my NHibernate mappings. If I had a custom repository for the \u00e2\u20ac\u0153CalculatedField\u00e2\u20ac\u009d class, I would test it separately.<\/p>\n<p>In upcoming posts I will explain my implementation of the DynamicContext, Anonymous, and custom TestAssertion classes.<\/p>\n<p>-=CE=-<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Several posts have been made lately concerning testing NHibernate Mappings. I thought I would share what I have done for the past few months. I create a test fixture for each class mapped in NHibernate. The tests in the fixture test loading, updating, saving, and deleting through NHibernate. Initially, I only tested loading, but later [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,3,8],"tags":[15,36,71],"class_list":["post-24","post","type-post","status-publish","format-standard","hentry","category-agile","category-test-driven-development","category-testing","tag-integration-testing","tag-tdd","tag-testing"],"aioseo_notices":[],"_links":{"self":[{"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/posts\/24","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/comments?post=24"}],"version-history":[{"count":2,"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/posts\/24\/revisions"}],"predecessor-version":[{"id":162,"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/posts\/24\/revisions\/162"}],"wp:attachment":[{"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/media?parent=24"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/categories?post=24"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/architester.com\/blog\/wp-json\/wp\/v2\/tags?post=24"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}