0

I read from "How to run test methods in specific order in JUnit4?" that...

making tests order dependent is a practice that the authors don't want to promote. Tests should be independent, they shouldn't be coupled and violating this will make things harder to maintain

How, in that case, should I test a method that gets a certain piece of data when I first have to set it?

For example, I have a String getStringAttribute(String key) and void setStringAttribute(String key, String attr). How should I test each of them? In order to properly test getStringAttribute(), I would probably need to test getting something that is not yet set and testing something that is already set.

Should I use setStringAttribute() within the testGetStringAttribute()?

Community
  • 1
  • 1
mushroom
  • 1,909
  • 3
  • 16
  • 33

5 Answers5

0

Call setStringAttribute() in your setUp method. This is the method taged with @Before. This is guaranteed to be called before your test method is called.

BetaRide
  • 16,207
  • 29
  • 99
  • 177
  • How do I then test a setter like `setStringAttribute()`? Don't I have to get it back in order to see if it has successfully set the value? Is there a best practice? – mushroom Oct 21 '15 at 05:26
  • IMHO testing mostly generated getters and setters is useless. But if you want, yes there is not way of testing a getter and a setter in an independent way. – BetaRide Oct 21 '15 at 05:31
0

Ideally, A test case should always set all the values it needs in its setup method (i..e the @Before method) and then clear all the values in its @After method.

So for your case, a possible way would be to create an object of the class and call its set method in the @Before class and then call the get method in your test case to test it. then in the @After class, clear all the objects.

for example:

ClassToTest classToTest;
String expectedValue = "somevalue";

@Before
public void setUp() {
    this.classToTest = new ClassToTest();
    this.classToTest.setStringAttribute("somekey", "somevalue");
}

@After
public void tearDown() {
    this.classToTest = null;
}

@Test
public void testValue() {
    assertEquals(this.expectedValue,this.classToTest.getStringAttribute("somekey"));
}

For testing the set method, one way to do that is using reflection: For example:

Field field = ClassToTest.class.getDeclaredField("stringAttribute");
field.setAccessible(true);
field.get(classToTest);
Sumit
  • 2,189
  • 7
  • 32
  • 50
0

First of all, I would say that it feels a bit strange to test setters and getters. At least from my point of view these methods should not contain any business logic.

As it was mentioned calling the setUp or any other method which is annotated with @Before is a good choice. If this setup is disturbing your other tests, just create a new test file and create there its own setUp method.

However, I would advice not even use the production methods to set up your system for testing. This might cause some other issues if you decide to change your setStginAttribute method. Thus, the best choice is to create raw data and then test your system based on that. That would mean that the test will be completely independent from the system and will not fail if you decide to change some other method than the one that you test.

Rufi
  • 2,529
  • 1
  • 20
  • 41
0

Typically testing getters and setters isn't needed since they are usually just return an attributes value. However if you are interested in checking to see if something was called and in what order you can use a testing framework like Mockito to do so, specifically its InOrder verification. This will give you more confidence that your code is actually doing what it should be doing in a given test.

kryger
  • 12,906
  • 8
  • 44
  • 65
Dale
  • 1,613
  • 4
  • 22
  • 42
-1

You would want to separate both methods and then write a test case for both of them. For example these are two methods I recently tested in JUNIT

@Test
    public void testCountFactors ()
    {
        assertEquals(1, Loops.countFactors(1));
        assertEquals(4, Loops.countFactors(6));
        assertEquals(2, Loops.countFactors(11));
        assertEquals(8, Loops.countFactors(30));
    }

    @Test
    public void testCountWhitespace ()
    {
        assertEquals(0, Loops.countWhitespace(""));
        assertEquals(0, Loops.countWhitespace("xyz"));
        assertEquals(10,
                Loops.countWhitespace("one two  three   four    "));
        assertEquals(8,
                Loops.countWhitespace("one\ttwo\n\nthree   four\n\t"));
    }

The assertEquals gives a desired value and the 'Loops.' calls upon the class and method and a specified input. In short by separating these methods rather than trying to test both simultaneously in one giant(spaghetti code) test case this simplified the testing of both of the methods.