0

I have an abstract class that features no abstract methods... How would one go about testing this? Can I simply import it into a test class and go about business as usual?

Example:

public abstract class SomeAbstractClass implements SomeOtherClass {

    // Some variables defined here
    private static final String dbUrl = System.getProperty("db.url");

    // Some public methods
    public String doSomethingToUrl(String url) {
        url = url + "/takeMeSomewhereNice";
    }

}

Say I pass in an arg for db.url of localhost:8080, and I wanted to test that the doSomethingToUrl method did output the new string... Would it still be in this format?

public class TestUrl {

    SomeAbstractClass sac = new SomeAbstractClass();

    @Test
    public void testUrlChange() throws Exception {

        String testUrl = "localhost:8080";

        assertThat("localhost:8080/takeMeSomewhereNice", 
            sac.doSomethingToUrl(testUrl));
    }
}
physicsboy
  • 5,656
  • 17
  • 70
  • 119
  • I am not sure whether this is common practice, but wouldn't mocking/stubbing the unit under test (aka. the abstract class) do the job? This, of course, only works iff. the tested method(s) do not call any abstract methods. – Turing85 Apr 13 '18 at 12:28
  • You create mocks/stubs. That is a small demo-implementation of that class just for the sake of that test. You can easily realize this with an anonymous class if the code is not too big. – Zabuzard Apr 13 '18 at 12:38
  • Possible duplicate of [Using Mockito to test abstract classes](https://stackoverflow.com/questions/1087339/using-mockito-to-test-abstract-classes) – Turing85 Apr 13 '18 at 12:43
  • Nah, not a duplicate for me @Turing85. – physicsboy Apr 13 '18 at 14:01

2 Answers2

7

You wouldn't be able to create an instance of just SomeAbstractClass, no - but you could create an anonymous subclass:

private SomeAbstractClass sac = new SomeAbstractClass() {};

You may well want to create a concrete subclass just for the sake of testing though - so that any time you do add abstract methods, you just need to put them there.

While I suspect you could use a mocking framework for this, I suspect it would add more complexity for little benefit, unless you need to check under what situations the abstract methods are called. (Mocks are great for interaction testing, but can be brittle for other purposes.) It could easily make for more confusing error messages (due to the infrastructure involved) as well.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I wondered why Eclipse generated the curly braces! Thanks for the info Daisy. I have seen Mockito used before, which would come in useful for stubbing things out but that was more of a simple case. – physicsboy Apr 13 '18 at 12:38
  • `SomeAbstractClass underTest = Mockito.mock(SomeAbstractClass.class, Mockito.CALLS_REAL_METHODS);`. Really not that complex. Your solution will only work iff. the abstract class has no abstract methods. If it has, you would have to create "dummy" implementations for the abstract methods, which imho is much more overhead than creating a mock with e.g. Mockito. – Turing85 Apr 13 '18 at 12:44
  • @Turing85: It's more complex than not using a mock at all - and also requires the dependency on Mockito which may not otherwise be used. I already talk about a dummy implementation just under the sample in my answer. I generally find that easier to use than a mock unless I'm actually doing interaction testing. (Sometimes I'll have several fakes, for different purposes.) My experience is that with mocks you can often get pretty confusing errors which may be worth it if you're really using mocking functionality, but aren't worth it if you're just trying to test other aspects. – Jon Skeet Apr 13 '18 at 12:51
0

You cannot initialize an abstract class, so your test class wouldn't compile as is.

You can either use an anonymous instance (the example below should suffice):

SomeAbstractClass sac = new SomeAbstractClass(){};

However, I would actually recommend you mock the class by means of a mocking framework such as Mockito or EasyMock.

Mena
  • 47,782
  • 11
  • 87
  • 106