5

I created a JUnit4 TestCase for my Shard class, but when I try to extend GroovyTestCase it does not run my @BeforeClass and @AfterClass methods.

Here is my code

import groovy.sql.*
import org.junit.*

class ShardUnitTests {
    static def shard
    static def sql
    static def mysqlserver = "REDACTED"
    @BeforeClass
    static void beforeClassSetUp(){
        def db = [url:'jdbc:mysql://${mysqlserver}:3306/test', user:'root', password:'password', driver:'com.mysql.jdbc.Driver']
        sql = Sql.newInstance(db.url, db.user, db.password, db.driver)
        shard = new Shard(sql: sql)
    }
    @AfterClass
    static void afterClassTearDown(){
        sql.execute("DROP TABLE test")
        sql.close()
    }
    @Test
    //Test that createObjectTable creates a table with 2 columns
    void testCreateObjectTable(){
        shard.createObjectTable("test")
        sql.rows("SELECT * FROM test"){meta ->
            assert meta.getColumnName(1) == "id"
            assert meta.getColumnName(2) == "data"
        }
    }
}

When I change the class definition to

class ShardUnitTests extends GroovyTestCase{

the beforeClassSetUp() and afterClassTearDown() methods are not called. Is there some other syntax I should be using for these methods, or is it just not compatible with GroovyTestCase?

Jonathan Woo
  • 103
  • 1
  • 6
  • Have you looked into `GroovyTestCase` class? – dmahapatro Apr 18 '14 at 16:22
  • Yes, I've looked at the API docs on CodeHaus. I know I can declare setUp() and tearDown() to run before and after each case, but I wanted to try a single DB setup and teardown for the whole set of tests. Is that possible? – Jonathan Woo Apr 22 '14 at 17:44
  • 2
    `GroovyTestCase` is `JUnit 3`-style, JUnit 3 doesn't support this. Have a look at this question http://stackoverflow.com/questions/7208593/how-can-i-get-beforeclass-and-afterclass-equivalent-in-junit3 – Dany Oct 16 '14 at 08:41
  • The question then becomes... why are you attempting to extend `GroovyTestCase` in the first place? Is it to gain access to the protected convenience methods in that class? – BalRog Oct 17 '14 at 19:31
  • If you are doing some 'interesting' database specific tests, you really should have a look at Spock. It gives you lots more functionality along with data driven tests. – Todd W Crone Oct 27 '14 at 23:14

1 Answers1

5

I use the @RunWith annotation to run these tests using JUnit 4 style to execute the before/after class methods. Example:

package org.apache

import org.apache.log4j.Logger
import org.bouncycastle.jce.provider.BouncyCastleProvider
import org.junit.*

import org.junit.runner.RunWith
import org.junit.runners.JUnit4

import java.security.Security

@RunWith(JUnit4.class)
class SomeClassTest extends GroovyTestCase {
    private static final Logger logger = Logger.getLogger(SomeClassTest.class)

    private SomeClass someClass

    @BeforeClass
    static void setUpOnce() {
        // Do things once for the whole test suite

        logger.metaClass.methodMissing = { String name, args ->
            logger.info("[${name?.toUpperCase()}] ${(args as List).join(" ")}")
        }

        Security.addProvider(new BouncyCastleProvider())
    }

    @Before
    void setUp() {
        // Do things before every test case
        someClass = new SomeClass()
    }

    @After
    void tearDown() {
        // Do things after every test case
    }

    @AfterClass
    static void tearDownOnce() {
        // Do things once for the whole test suite
    }

    @Test
    void testShouldDoSomething() {
        // Arrange

        // Act
        int result = someClass.doSomething()

        // Assert
        assert result == 0
    }
}
Andy
  • 13,916
  • 1
  • 36
  • 78
  • Very good... best of both worlds. But in Java anyway you can only "RunWith" one runner. Unless this is different in Groovy (I'm currently a neophyte) this could be a bit of a drawback... – mike rodent Jan 30 '18 at 20:48