C# – How to test with multiple input combinations

cunit testing

I have a piece of code that I need to test, which is layered in three parts:

  • Web API Controller
  • Persistence/Logic Layer
  • System calls for persistence

It's the basic GET/POST/PUT/DELETE call system. For instance, in the controller I have the GetAll method which calls into a Get in the second layer, which in turn calls either some Sql database method either another web api method.

The scenarios: Mock the second layer and call the controller. Mock the system calls and call the second layer. Mock the system calls and call the controller.

For each scenario, I have multiple test inputs, for each method in the controller/second layer.

What would be the best way to do it? I want to have as little as possible code duplication.

I can use a datasource attribute on my test and have for each test a layer value that would select the type of mocking that I would to do, and for each layer value, I would add test data(input parameters). But that test data would be common for all layer values, which would mean that I would have to duplicate it for each layer value. Also I would have the same layer values for all methods in the controller/persistence layer, which again would be a duplicate.

I would like to factor out in some way the layer values, which would be common for all tests(think of class level values) and also have specific input values for each method in the controller(method level). And for each method then, I would have a test in which I would do some sort of a cross product in between the general layer values and the specific method input values. How could I achieve that?

Best Answer

I would suggest focusing on behavior tests rather than duplicating the same tests for different layers. I mean that I would test all the layers all together in different scenarios. For example:

  • Given there are no items, get item X should return Not Found
  • Given an item X exists, adding same item should return Conflict

So there is no need to test same tests with different inputs, because what actually maters is not the values but the use cases.

For these tests I would suggest to use some in memory implementation of database which will allows resetting the database for each test. A good tool for this purpose might be Effort if you use Entity Framework https://effort.codeplex.com There are also other tools available depending on your ORM framework or Data Access Layer.

Related Topic