0

Currently, I'm working on testing a Class (let's say Message for example) that has CRUD operations. Following the methodology used behind, I want to test all the operations in exact Create, Read, Update and Delete order.

Since the order of execution of test cases in JUnit is dependent on JVM, I need some proper way to ensure that the unit test cases are executed in the given order.

So far, I've come up with following strategies:

  1. Using @FixMethodOrder(MethodSorters.NAME_ASCENDING) in JUnit 4 to execute methods in ascending order of their names. However, this requires renaming test cases and didn't seem the best way to me as if in future more test case need to be added existing test cases may need to be refactored.

  2. Using different Message object for each test case. However, I will need to create/initialize it before and delete it after each test case. This for me seems to go against the notion of unit-testing, as to test update I'll have to call create and delete, which no longer makes this a unit test case. If create fails, this would result in read, update and delete tests in failing as well, even when there's nothing wrong with them.

  3. Using a single test to call other test methods. This to me seems the more appropriate solution than other two. If create fails, it should stop other three tests from running and such.

So is there any better way to achieve this or any alternative way to test such a model?

Currently using JUnit4 and thinking of moving to JUnit5 if no solution satisfies my case.

2
  • 1
    Think of upgrading to JUnit 5? junit.org/junit5/docs/current/user-guide/… Commented Jul 31, 2019 at 11:09
  • Keeping it as a last resort as existing code will need a lot of refactoring. Commented Jul 31, 2019 at 11:13

2 Answers 2

3

What you are describing are not Unit Tests.

A Unit Test should never:

  • Touch a database
  • Touch a filesystem
  • Touch a network
  • Depend on another test

What you should do instead is to mock access to such external resources so that your tests are isolated and independent.

Sign up to request clarification or add additional context in comments.

3 Comments

Your point is valid and I do agree, however it doesn't answer my question. My use case needs me to test db queries as well. Essentially the code I need to test methods that query db to perform crud operations. These queries are dependent on some existing data in the db that is unpredictable in production and hard to mock. How would you suggest me to test them? I'm also looking into Mockito right now.
That depends mainly on the design of your classes. But the main idea is to test the business logic and mock all dependencies. This way you will eventually chase this external dependency "into a corner" where you cannot reasonably mock it any more. These queries still need to be tested but since unit testing covered the business logic their surface area should be greatly reduced so you can test them with a few integration tests to verify that the communication with the database works.
As for the order. Just don't do it. Have before/after methods that prepare necessary data before the test runs and clean it afterwards. Test order will come around to bite you sooner or later.
1

Your option 2 is the most appropriate one, even if this surprises you: You should try to make your tests independent of each other such that execution order is not an issue.

And, it is a normal situation that, for the testing of some method a, you need to call other methods b, c, ... during test setup, validation or teardown. Your are right, if these other methods fail then tests for method a will probably fail as well - or succeed where they should fail.

This, however, is not a problem if you also have tests for those other methods b, c, ... in place. If there is a bug in, say, b, then some test for b would fail and some other tests for a. From the pattern of failing and succeeding tests you would then have to deduce where to search for the root cause of the failing tests.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.