2

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?

4
  • Are you asking how to test a method on a class using different inputs? In other words, the method would run multiple times, just with different inputs each time? What testing framework are you using? Jul 27, 2015 at 18:28
  • Unit tests should be small and clear about what is being tested. So don't focus on "as little as possible code duplication". Test setup/initializer is a great place to place common data. Also unit tests can be code generated in some cases.
    – Tzu
    Jul 27, 2015 at 21:33
  • @AndyWiesendanger The answer is yes. I'm using Telerik's JustMock for mocking and Visual Studio's library for unit testing.
    – MciprianM
    Jul 28, 2015 at 8:16
  • 1
    VS library - you mean MSTest? Ah, so are you asking this - stackoverflow.com/questions/1010685/… Jul 28, 2015 at 17:08

1 Answer 1

1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.