Create Data Driven Unit Tests in an NHibernate Environment

时间:2015-10-06 08:33:57

标签: c# unit-testing nhibernate mstest

Background

We are slowly updating a very old application (based on "normal" SqlCommand queries and everything that comes with it) with some new code. To enhance stability and ease further development, we introduced NHibernate into the mix, along with good programming practices and what not.

So now, whenever a new module (not that the application is actually modular, but lets call it that) needs a large enough update, we break out all functionality into the "new" world of NHibernate and create a facade for the old code, so it keeps working.

Setup

I am creating Unit Tests for the facades. For this, I created a base class that all unit test classes are inheriting from. This class, on TestInitialize

  • creates the database schema using NHibernates "SchemaExport"
  • creates a "legacy" schema that consist of all tables that are not yet mapped by Nhibernate, but are needed by the facades to work

Every TestClass (inheriting from the one above) has its own DataSet.sql which is executed on TestInitialize, which

  • fills mapped Nhibernate tables with test specific data
  • fills the legacy tables with test specific data
  • fills a testExecutions table with input and expected output for each test run

The TestMethod of each TestClass then iterates over the testExecutions rows, creates the required objects (NHibernate), calls the facade it tests, and Asserts the returned data against what was defined in the testExecutions table.

Problem

The testing works fine, I get exactly the results I expect, but...

I have a big problem with this approach: Every test run visible in the test outputs is actually many many test executions. But from the outside, it just looks like a single test, even if the test itself actually runs the tested facade method many times over, with new data each time

I read about Data Driven Unit Tests and thought that it was literally exactly what I was already doing. So, instead of using my own things, I decided I should use that.

But the problem is: The TestContext.DataRow does obviously not know about NHibernate, so I don't actually get the objects required for testing, but a DataRow object with all data filled in the "old" way of Sql objects.

Is there a way to "teach" DataSource to return Nhibernate objects? Do I have to write my own DataSource attribute to accomplish this? How would that need to look?

Or is there another way

Is there a way to make my TestMethods to record the iteration over the testExecutions the same way a Data Driven test would do? So I don't have one Test, but the actual amount of tests run inside the method?

2 个答案:

答案 0 :(得分:2)

你和MsTest绑定了吗?考虑使用NUnit,它具有完全适用于您的场景的扩展点。查看[TestCaseSource]属性http://www.nunit.org/index.php?p=testCaseSource&r=2.5.9,它允许您引用从中获取测试数据的方法。您从那里获取的数据将显示为单独的单元测试。

该方法必须是静态的,即你必须通过使用静态成员来传递NHibernate会话,你可以在类或测试设置方法中设置它。

答案 1 :(得分:0)

好的,我设法让它现在正常工作,虽然我不得不改变一些代码。

我的问题的根源是,我使用[TestInitialize]来创建数据库结构(架构,表格等),包括设置数据和测试运行本身。

MSTest和NUnit都看到不同的东西。在运行测试之前,测试运行需要存在。这意味着,在[TestInitialize](或分别为[SetUp])运行时,会查询[DataSource](或[TestCaseSource])。

显然这在我的情况下不起作用,因为我只是在生成表结构的相同方法中为测试运行创建了数据。

我重新设计了我的测试套件,以便测试运行数据包含在一个单独的文件(Access DB)中,而conext(模式,表格,初始数据)是针对每种测试方法创建的。

如果没有导致[TestInitialize][TestCleanup]方法仅在[DataSource] d测试的第一次迭代中运行的烦恼Visual Studio 2010 Bug,这已经可以正常工作了,所以我不得不把所有这些都放在类的正常构造函数中......

尽管如此,现在一切正常,我可以看到实际运行的测试数量: - )