Adopting Builder Pattern with Abstract class

Builder Pattern helps simplify constructor and increase readability with fluent interface. It can also be handy to make the class immutable (not demonstrated here).
Here is an example if you have an abstract base class in the way:

The abstract base class:

public abstract class BaseClass {

private String name;

protected static abstract class BaseBuilder<T extends BaseClass, B extends BaseBuilder>{
  protected T actualClass;
  protected B actualClassBuilder;

  protected abstract T getActual();
  protected abstract B getActualBuilder();
  protected BaseBuilder() {
    actualClass = getActual();
    actualClassBuilder = getActualBuilder();
  }
  public B name(String name) {
    actualClass.setName(name); return actualClassBuilder;
  }
  public T build() { return actualClass; }
}

private void setName(String name) { this.name = name; }

private String getName() { return name; }

}

The concrete, extending class:

public class ConcreteClass extends BaseClass {
  public static class Builder extends BaseBuilder<ConcreteClass, Builder> { 

    public Builder anotherField(String anotherField) {
            actualClass.setAnotherField(anotherField);
            return this;
        }

        @Override
        protected ActionTask getTask() {
            return new ActionTask();
        }

        @Override
        protected Builder getBuilder() {
            return this;
        }
}

To use it:

ConcreteClass myConcreteObject =
  new ConcreteClass.Builder()
    .name("one")
    .anotherField("two")
    .build();

Mocking static Logger without PowerMock

Suppose you have a class that uses a static Logger to log some error, and you would like to unit test including the message logged. One approach is to use PowerMock because the Logger is usually declared static in your class. However for logging, you don’t need to add PowerMock to your dependency if you don’t already use it. Here’s an example:

public class MyClass {
private static final Logger LOGGER = Logger.getLogger(MyClass.class);
public void myMethod() {
try {
// ...
}
catch ( ... ) {
LOGGER.error("my error message");
}
}
}

 

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
@Mock
private Appender logAppender;
@Captor
private ArgumentCaptor loggingEventArgumentCaptor = ArgumentCaptor.forClass(LoggingEvent.class);</code>

@Before
public void setUp() {
Logger logger = Logger.getLogger(ConfigBasedActionLookupService.class);
logger.addAppender(logAppender);
logger.setLevel(Level.INFO);
}

@Test
public void myMethod_invalidConditions_shouldLogError() {
verify(logAppender, times(1)).doAppend(loggingEventArgumentCaptor.capture());
LoggingEvent actualLoggingEvent = loggingEventArgumentCaptor.getValue();
assertThat(actualLoggingEvent, is(notNullValue()));
assertThat(actualLoggingEvent.getRenderedMessage(), containsString("my error message"));
}