简体   繁体   中英

Junit for a Java method which is driven by a boolean flag

The Java method looks like the below

 public String generateResponseXML(List<Error> parsingErrors)
                throws XMLStreamException {


            Map<String, String> additionalNamespaces = new HashMap<String, String>();
            if (successfulResponse){
            additionalNamespaces.put(
                    ServiceInterface.COMMON_NAMESPACE_PREFIX,
                    ServiceInterface.COMMON_NAMESPACE);
            additionalNamespaces.put(
                    ServiceInterface.COMMON_NAMESPACE_PREFIX,
                    ServiceInterface.COMMON_NAMESPACE);
            }
            else {
                additionalNamespaces.put(
                        ServiceInterface.NAMESPACE_PREFIX,
                        ServiceInterface.NAMESPACE);
                additionalNamespaces.put(
                        ServiceInterface.NAMESPACE_PREFIX,
                        ServiceInterface.NAMESPACE);
            }

When I write the below code in my Junit Test class:

String responseXML = xyzPayment.generateResponseXML( Errors );

It doesn't cover the code when the successfulResponse needs to be true. How to cover the code where the successfulResponse is true, rather only covers the else part. Kindly guide me on how to achieve code coverage here?

So, successful response is an member variable, right?

If you need to be able to set this variable in a test, but don't want to expose a setter for it, you can make it package-private ( https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html ). Then you would make your test class have the same package as the class you are testing.

So the class would have something like:

public class MyClass {
    boolean successfulResponse = false;
    //code ...
}

Then your test would be like:

xyzPayment.successfulResponse = true;
String responseXML = xyzPayment.generateResponseXML( Errors );

Just set the successfulResponse field to true in your test

Even if the field is priate you can still set it to true using reflection:

Field successfulResponseField = YourClass.class.getDeclaredField("successfulResponse");
successfulResponseField.setAccessible(true);
successfulResponseField.set(yourClassInstance, true);

I have to assume that successfulResponse is a field. You haven't shown us how that field gets set. Your test will need to call whatever method sets successfulResponse to true .

For example, it might happen in the constructor:

public MyClass(boolean successful) {
    this.successfulResponse = true;
}

In this case, your test needs to call the constructor in that way:

MyClass xyzPayment = new MyClass(true);
String responseXML = xyzPayment.generateResponseXML(errors);

There are a few ways you might get hold of an object with the field set:

  • directly, if it's a public field: myObj.field = true
  • via a method call, eg a setter myObj.setField(true)
  • constructor, as shown
  • a static factory method MyClass myObj = MyClass.successfulInstance()
  • (and more)

Since you're the one writing the tests, it seems likely you're the one writing the class under test -- so it's up to you to know why the field exists, and how it gets set.

If you want to test the method without changing your implementation, you can use something like:

MyClass myTestingClass = new MyClass() {
    @Override
    public String generateResponseXML(List<Error> parsingErrors) throws XMLStreamException 
    {         
        successfulResponse = true;
        super.generateResponseXML(parsingErrors);
    }};
myTestingClass.generateResponseXML(Errors);

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