1

I am writing a test for a class which has a setup

class A
{

  private String name;
 public String getName()
{
   return "Hello "+ name;
}
 public void setName(String name)  
 {
    this.name = name;
 }

My test class

TestA
A a = new A();
    {
     @Before
     void  setup()
    {

         a.setName("Jack");
    }

    @Test
    public void testTom()
    {
        assert(a.getString(), "Hello Tom");
    }

    @Test
    public void testJack()
    {
       assert(a.getString(), "Hello Jack");
    }

How to change the value of name between the methods since @Before calls for every test method? ie) if execute testJack then the output should be Hello Jack. I tried with @Parameters but before that setup is getting called so i couln't acheive this functionality.

Stefan Birkner
  • 24,059
  • 12
  • 57
  • 72
Shriram
  • 4,343
  • 8
  • 37
  • 64
  • You will have to write a.setName("Jack") within each test - or randomize it and put the randomized value in some variable that you can expect upon. You can, however, create the A-object outside. E.g private A a; then in before add a = new A(); and in each test just add a.setName(); in the beginning of each test. Wierd case anyway :P. – vegaasen Feb 02 '17 at 14:54
  • Is there any way to parameterize so that only name will change and remaining will work as expected. Since i have given as an example here. Just assume the scenario of 30 lines of code in setup that needs to be called before each test case. Passing a variable is one option. Is there any option – Shriram Feb 02 '17 at 14:58

2 Answers2

0

First, the code:

 @Before
 void  setup()
{
     A a = new A();
     a.setName("Jack");
}

Doesn't do anything which the Tests can see. You're creating a local variable a which goes out of scope almost immediately.

@Before is designed to set and reset a state or context before each Test is run. It doesn't vary unless something it relies on changes between invocations.

You could create a Stack as an instance variable and pre-populate it in a @BeforeClass method, and have @Before pop a value to be used every time it's called. This is unadvisable as it assumes that the Tests will be run in some particular order. It's much cleaner and clearer to just declare different values inside each Test.

WillD
  • 875
  • 1
  • 7
  • 14
  • sorry about that. changes to global variable. Also i can see parameterization for a single method instead of multiple methods. – Shriram Feb 02 '17 at 14:59
0

There is simply no point in doing that; as your real problem is rooted in your statement "Just assume the scenario of 30 lines of code in setup".

If you need 30 lines of setup code, then your code under test is not following the "single responsibility principle" and doing way too many different things.

Of course, you can turn to "data driven" testing to somehow get there (see here for example); but that would be fixing the Y side of an XY problem.

I know, it sounds harsh: but you better step back; and learn about doing reasonable OO design (for example based on SOLID). Then you rework your code to not need 30 lines of setup code.

You see, if your code is so hard to test; I guarantee you: it is also hard to understand, and will be close to impossible to maintain/enhance over time. And beyond that: it will be even hard to get your code to be "correct" in the first place.

Long story short: have a look in these videos and improve your design skills.

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248