简体   繁体   中英

Junit: local variables and void methods

I'm fairly new to unit testing and have been reading a lot of material online, but I'm having a little trouble figuring stuff out.

For example: If I have the following piece of code :

public class RandomClass
{
  int a = 4;
  public void foo(Object obj)
  {
    if(a == 4)
    {
      AnotherObject anotherObj = new AnotherObject();
      anotherObj.setAttribute(obj.getFiled());
      //Method call that will be suppressed 
      Anotherclass.anotherMethod(anotherObj);
    } 
  }
}

I thought of writing my junit test case like this:

@Test
public void testFoo()
{
  int a=4;
  RandomClass randomClass = new RandomClass();
  Object object = new Object();
  object.setField("hey");
  randomClass.foo(object);
}

I have a couple of questions here. How exactly do I set the integer a from my junit? The way I'm setting it right now doesn't the unit test case any impact. When I debug the unit test, the value of a is NULL so it never passes the if condition!

Also, the method foo returns a void so what can I possibly test/assert?

There are two major techniques when writing unit tests:

  1. Checking the external contract of your class under test. Meaning: you try to write testcases for RandomClass that know nothing about AnotherClass . Instead, your test code only observes behavior of RandomClass objects. In other words: you really don't care about the internal implementation details of RandomClass - because all the things you "want to see" can be observed by checking what RandomClass objects return when you call methods with specific parameters. Occasionally you get there by adding (package protected) getter methods that allow you to inspect some internal state of your class under test.
  2. But sometimes that might not be "good enough"; for example when you know that your class under test must be using some other objects to get its job done. In such situations, you should be looking into mocking objects. In your case, you might want to create a mocked instance of AnotherClass ; and then you would use dependency injection in order to provide that object to your class under test.

You see, you actually wrote "hard to test" code - because you are calling new for AnotherClass in your production code. That doesn't seem like a big deal, but depending on what AnotherClass is about ... you really shouldn't do that!

In any case; I recommend you to look into these videos to learn how to write code that works better for unit testing.

A test normally starts with a "setup", "prepare", or "arrange" step, where it creates or modifies the object under test so that it is in the state needed by that particular test.

So, if field a in the RandomClass object needs to have a value 4 (for example), then the test needs to either create the object passing this value as a constructor argument, or to set the value in the object by calling a setter method or by directly accessing the field. In the worst case, you might need to use Reflection to set the field, but that would indicate a design issue in the class being tested.

The next step is to exercise the code under test. This is the "act" step, in the "Arrange, Act, Assert" terminology (AAA, for short).

Finally, the final step is to "assert" (verify) the code being tested did what is was supposed to do.

If the method being tested has void return type, then the test should verify it did what was expected either through state verification or through behavior verification.

In the first case, the test would call some getter method in the object under test, and use it in an "assert" of some kind (for example, an assertEquals(expectedValue, actualValue) ).

In the second case, the test would use some mocking library in order to verify that expected calls were made from the code under test to one or more dependencies (other objects or classes on which the class under test depends). For example, here the test could verify that RandomClass#foo did actually call Anotherclass.anotherMethod(...) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM