How to execute different #Before in JUnit - junit

Currently If I write #Before method, it will be executed for each of tests present in the JUnit. However i want the following.
I need to have multiple #Before methods and only needed should be executed for each test.
Example:
#Before
setUpBeforeForTest1AndTest3()
#Before
setUpBeforeForTest2AndTest4()
For test1 and test2, setUpBeforeForTest1AndTest3() should be executed and for other tests setUpBeforeForTest2AndTest4 should be executed.
How i can acheive this?

you can not achieve that this way.
To do this, make 2 distinct test classes, one with test 1 and test 3, one other with test 2 and test 4.
If you have common methods needed in all your test classes either externalize them in a helper or make a super class (usually called 'TestBase' or something similar) providing them.

You can use Junit
#Rule TestName
Then in your
#Before, depending on the test method name, do something differently.

Related

JUnit 5 -- reuse a nested test class with different state?

Student here. In JUnit 5, what is the best way to invoke a #Nested test class multiple times, but with slightly different state each time?
I see that JUnit 5 has an (experimental) #ParameterizedTest feature that is based on the (non-experimental) #TestTemplate feature, but both of those apply to test methods only, rather than nested test classes.
I have a heavy #Nested test class that needs to be invoked once for each value of an enum (preferably with a distinct #Tag value for each invocation), and I would prefer to avoid the "copy-and-paste" method of parameterization.
It is not currently possible to execute a test class multiple times in JUnit Jupiter.
To participate in the discussion, see the following issue: https://github.com/junit-team/junit5/issues/878

Is it possible to specify which Before method runs in JUnit, and if so, how?

I have a test suite which tests two different things in the same class. I have a before method that initialises some fields for the test methods to use. However, I have a group of test methods that uses the first set of field, and another group that uses the second, but not the first. I know it's possible to split the before action over different before methods, but is it also possible to specify which one runs before each test?
Concrete example:
#Before
public void before1() {...}
#Before
public void before2() {...}
#Test
public void test1() {
//Only before1 runs
}
#Test
public void test2() {
//Only before2 runs
}
This is a simple representation, but I have much more tests that use either of these befores.
Everything you've stated in your question is pointing to splitting up your tests into 2 separate classes. I am guessing that the two groups you have are testing distinct features of your code and may even have some commonality in the test names. Take all of the tests that require before1 into a test class and all the tests that require before2 into another test class. You can name these new test classes according to the grouping of behaviour you're testing.
For example if half of your tests are for success scenarios and half are testing failure scenarios, put these into classes named something like FooSucceedsTest and the failures into FooFailsTest.
There is no guarantee on the order of a #Before executing just as there's no guarantee on a #Test order of execution.
The solution is to do any setup a test is dependent on in the #Test itself and use the #Before for common setup before test execution.

Guideliness to write junit test cases for if,loop and exception

I'm new to Junit. I want to write test cases for if condition,loops.
Do we have any guidelines or procedure to write test cases for if,loop conditions?
Can anyone explain with an example?
IF Age < 18 THEN WHILE Age <> 18
DO ResultResult = Result +1 AgeAge = Age +1 END
DO Print “You can start driving in {Result} years”
ELSE
Print “You can start driving now!”
ENDIF
You want one test case for each major scenario that your code is supposed to be able to handle. With an "if" statement, there are generally two cases, although you might include a third case which is the "boundary" of the two. With a loop, you might want to include a case where the loop is run multiple times, and also a case where the loop is not run at all.
In your particular example, I would write three test cases - one where the age is less than 18, one where the age is exactly 18, and one where the age is over 18. In JUnit, each test case is a separate method inside a test class. Each test method should run the code that you're testing, in the particular scenario, then assert that the result was correct.
Lastly, you need to consider what to call each test method. I strongly recommend using a sentence that indicates which scenario you're testing, and what you expect to happen. Some people like to begin their test method names with the word "test"; but my experience is that this tends to draw attention away from what CONDITION you're trying to test, and draws attention toward which particular method or function it is that you're testing, and you tend to get lower quality tests as a result. For your example, I would call the test methods something like this.
public void canStartDrivingIfAgeOver18()
public void canStartDrivingIfAgeEquals18()
public void numberOfYearsRemainingIsShownIfAgeUnder18()
From my understanding of writing in junit for java ,we were used to create a source code into different blocks is the code conventional,and used to pass the values as args to the function from the test cases so the values will steps into the block statements ,and passes the test cases .
For example you are having the variable as age by assuming as functionName(int age), for testing you should pass the integer from the test case as functionName(18) it will steps into the statements and will show you the status of the test case.Create test case for a testing class write test case for the functions
UseClass classObj=new UseClass();// it should be your class
#Test
public void testValidateAge() {
classObj.validateAge("20");
assertEquals(200,"");
}
Correct me if 'm wrong :)

How can I make JUnit let me set variables in one test case and access them in other if they are in the same class

Let say I have a test class called MyTest.
In it I have three tests.
public class MyTest {
AnObject object;
#Before
public void setup(){
object = new AnObject();
object.setSomeValue(aValue);
}
#Test
public void testMyFirstMethod(){
object.setAnotherValue(anotherValue);
// do some assertion to test that the functionality works
assertSomething(sometest);
}
#Test
public void testMySecondMethod(){
AValue val = object.getAnotherValue();
object.doSomethingElse(val);
// do some assertion to test that the functionality works
assertSomething(sometest);
}
Is there any way I can use the value of anotherValue, which is set with its setter in the first test, in the second test. I am using this for testing database functionality. When I create an object in the DB I want to get its GUID so I can use this to do updates and deletes in later test methods, without having to hardcode the GUID and therefore making it irrelevant for future use.
You are introducing a dependency between two tests. JUnit deliberately does not support dependency between tests, and you can't guarantee the order of execution (except for test classes in a test suite, see my answer to Has JUnit4 begun supporting ordering of test? Is it intentional?). So you really want to have dependencies between two test methods:
you have to use an intermediate static value
as Cedric suggests, use TestNG, which specifically supports dependencies
in this case, you can create a method to create the line, and call it from both methods.
I would personally prefer 3, because:
I get independent tests, and I can run just the second test (in Eclipse or such like)
In my teardown in the class, I can remove the line from the database, the cleanup. This means that whichever test I run, I always start off with the same (known) database state.
However, if your setup is really expensive, you can consider this to be an integration test and just accept the dependency, to save time.
You should use TestNG if you need this (and I agree it's fairly common in integration testing). TestNG uses the same instance to run your tests, so values stored in fields are preserved between tests, which is very useful when your objects are expensive to create (JUnit forces you to use statics to achieve the same effect, which should be avoided).
First off, make sure your #Test 's run in some kind of defined order
i.e. #FixMethodOrder(MethodSorters.NAME_ASCENDING)
In the example below, I'm assuming that test2 will run after test1
To share a variable between them, use a ThreadLocal (from java.lang).
Note that the scope of the ThreadLocal variable is to the thread, so if you are running multiple threads, each will have a copy of 'email' (the static in this case implies that its only global to the thread)
private static ThreadLocal<String> email = new ThreadLocal<String>();
#Test
public void test1 {
email.set("hchan#apache.org);
}
#Test
public void test2 {
System.out.println(email.get());
}
You should not do that. Tests are supposed to be able to run in random order. If you want to test things that depend on one value in the database, you can do that in the #Before code, so it's not all repeated for each test case.
I have found nice solution, just add Before annotation to the previous test!
private static String email = null;
#Before
#Test
public void test1 {
email = "test#google.com"
}
#Test
public void test2 {
System.out.println(email);
}
If you, like me, googled until here and the answer didn't serve to you, I'll just leave this: Use #BeforeEach

Junit test class variable scope

I have a Junit test class with two tests in it. test 1 will add an element to an ArrayList and passes it to the main class to do some logic and returns true. Test two should use the same arrayList and calls the same main class do the same logic but by the time the list comes to second test methods, its getting null.
I declared it as class variable. My questions is.. when I assign values to a class variable in a test method, will I not have access to the values in next test method? If yes, how should i retain the values.
Thanks,
Mahi
The way variables work in jUnit is that they get initialized before each test. So if you added value x to a list in Test1, it won't be there when you run Test2. If you want to some kind of initialization before each test, use the setup method.