intellij junit working directory

if the working directory for junit test is not properly set, the resource file might not be able to be loaded if relative path is used.

By default, Intellij uses project path as working directory. However if you have sub-modules which are in the sub directories, the junit test might have problem running locally.

To set it, go to the run/debug config and select the junit, you should be able to see the ‘working directory’ option there.

To set default, go to the run/debug config, click ‘default’ and select junit, in the ‘working directory’,set ‘$MODULE_DIR$

JUnit test with Mockito and Spring

Deveop Mockito, Spring and JUnit tests

The code source bellow presents a JUnit test using Spring-test and Mockito framework.

@RunWith(SpringJUnit4ClassRunner.class) runs the test with Spring custom runner that will load Spring application context.
@Autowire associate invoiceService reference to the InvoiceService instance.
@Before annotation executes the setup method before the test.
MockitoAnnotations.initMocks(this) scans the class annotation, instanciates invoiceDaoMock and inject it into the InvoiceService bean.
when(.(any())).thenReturn() associates a return value with method execution parameters.

//Load Spring contexte
@ContextConfiguration(locations = {"classpath:/application-context.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
public class InvoiceServiceTest {
     
    // Create Mock
    @Mock
    private IInvoiceDao invoiceDaoMock;
     
    @InjectMocks
    @Autowired
    private IInvoiceService invoiceService;
     
     
    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }
 
     
    @Test
    public void testProcessInvoice() throws SQLException {
         
        // specify mock behave when method called
        when(invoiceDaoMock.save(any(Invoice.class))).thenReturn(Long.valueOf(1));
         
        Assert.assertNotNull(invoiceService);
        Map<Product, Integer> products = new HashMap<Product, Integer>();
        products.put(new Product("labtop", BigDecimal.valueOf(1255.50)), 2);
        Invoice invoice = invoiceService.processInvoice(products);
         
        Assert.assertEquals(1255.50 * 2, invoice.getTotal().doubleValue(), 0);
         
    }
}

 

Also look at this post for using @RunWith(MockitoJUnitRunner.class)

FROM HERE

use log4j in junit test assertions

I need to confirm that some error/warnings are logged in the code being tested. The logger is usually private static final that we cannot get from the junit. The following pattern would be able to achieve it.

 

	@Test
	public void testLogMessageIsSent() {
		Logger logger = Logger.getLogger(ClassUnderTest.class);

		ByteArrayOutputStream out = new ByteArrayOutputStream();
		Layout layout = new SimpleLayout();
		Appender appender = new WriterAppender(layout, out);
		logger.addAppender(appender);

		try {
			ClassUnderTest.methodThatLogsAMessage();

			String logMsg = out.toString();

			assertThat("log message should not be null", logMsg, notNullValue());
			assertThat("Should contain warning message", logMsg, containsString(SOME_VALUE));

		} finally {
			logger.removeAppender(appender);
		}
	}

Proper way to access file resources in junit tests

As I was refactoring some JUnit tests recently I was reminded of an important fact on the proper way to read in a file.
In maven any file under /src/test/resources is automatically copied over to /target/test-classes. So for example lets say I need to read in a wsdl in my test. So I place the wsdl in the resources folder: /src/test/resources/test.wsdl. Now at first it might be tempting to reference the file with the following code:

File testWsdl = new File("/src/test/resources/test.wsdl");

and this will actually work on a windows machine; but what about linux, cygwin, or even solaris. Your next improvement might be to replace the '/' with File.separator:


File testWsdl = new File(File.separator + "src" + File.separator + "test"
    + File.separator + "resources" + File.separator + "test.wsdl");

This still isn’t the best solution which is presented below:

URL url = this.getClass().getResource("/test.wsdl");
File testWsdl = new File(url.getFile());

Using the class’s resource will locate the file in the test’s classpath, which happens to be /target/test-classes. And this final solution will work on windows, linux, cygwin, and solaris.

Spring ResourceLoader

if it is in the context of Spring we can
    @Autowired
    private ResourceLoader resourceLoader;

    resourceLoader.getResource("classpath:xxx/file:xxx");
The benefit of this is for testing, we could mock the ResourceLoader and get mock resources.
FROM HERE

jUnit assertThat matchers

Matchers is an external addition to the JUnit framework. Matchers were added by the framework called Hamcrest. JUnit 4.8.2 ships with Hamcrest internally, so you don’t have to download it, and add it yourself.

Matchers are used with the org.junit.Assert.assertThat() method, which looks like this:

    public void assertThat(Object o, Matcher matcher){
        ...
    }

You can implement your own Matcher’s, but JUnit (Hamcrest) comes with a few builtin matchers you can use. Here are a few examples:

import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
import org.junit.Test;

public class MyMatcherTest {

    @Test
    public void testWithMatchers() {
        assertThat("this string", is("this string"));
        assertThat(123, is(123));
    }
}

The assertThat() method takes an object and a Matcher implementation. It is the Matcher that determines if the test passes or fails. The assertThat() method just takes care of the “plumming” – meaning calling theMatcher with the given object.

JUnit (Hamcrest, really) comes with a collection of builtin matchers you can use. In the example above, theorg.hamcrest.CoreMatchers.is() method is used to create a Matcher. The Matcher returned by is()returns true, if the two values compared are equal, and false if not.

The assertThat method throws an exception if the Matcher returns false. If the Matcher returns true, theassertThat() method returns normally. How the Matcher returns true or false, I will get back to later in this text. Right now just imagine that it can.

 

Chaining Matchers

You can chain some matchers, for instance like this:

@Test
public void testWithMatchers() {

    assertThat(123, not( is(345) ) );

}

Notice the chained call not( is(345) ). This is really two matchers combined. The is() method returns one matcher, and the not() method returns another. The matcher returned by not() negates the matcher output of the matcher given as input. In this case, it is the output of the matcher returned by the is() method, that is negated.

 

Core Matchers

Before you start implementing your own Matcher‘s, you should look at the core matchers that come with JUnit already. Here is a list of the matcher methods:

 

Core
any() Matches anything
is() A matcher that checks if the given objects are equal.
describedAs() Adds a descrption to a Matcher
Logical
allOf() Takes an array of matchers, and all matchers must match the target object.
anyOf() Takes an array of matchers, and at least one of the matchers must report that it matches the target object.
not() Negates the output of the previous matcher.
Object
equalTo() A matcher that checks if the given objects are equal.
instanceOf() Checks if the given object is of type X or is compatible with type X
notNullValue() +
nullValue()
Tests whether the given object is null or not null.
sameInstance() Tests if the given object is the exact same instance as another.

Actually, all of the above are static methods which take different parameters, and return a Matcher.

You will have to play around with matchers a little, before you get the hang of them. They can be quite handy.

 

Custom Matchers

You can write your own matchers and plug into the assertThat() method. Here is an example:

public static Matcher matches(final Object expected){

    return new BaseMatcher() {

        protected Object theExpected = expected;

        public boolean matches(Object o) {
            return theExpected.equals(o);
        }

        public void describeTo(Description description) {
            description.appendText(theExpected.toString());
        }
    };
}

The static method matches() creates a new matcher and returns it.

This matcher is an anonymous subclass of the class BaseMatcher. The JUnit documentation states that you should always extend BasreMatcher rather than implement the Matcher interface yourself. Thus, if new methods are added to Matcher in the future, BaseMatcher can implement them. Your subclasses will then automatically get those methods too. That will avoid breaking your code.

Here is how to use this custom matcher:

@Test
public void testThat() {
    MyUnit myUnit = new MyUnit();

    assertThat(myUnit.getTheSameObject(), matches("constant string"));

}

Simple, isn’t it? You just embed the call to the static method matches() inside the assertThat() method.

 

FROM HERE

Spring Junit Test

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:/applicationContext.xml") //or something like "file:WebContent/WEB-INF/applicationContext.xml"
@TransactionConfiguration(defaultRollback=true, transactionManager="transactionManager")//this ensure that spring would rollback the transaction so that the test will not change the database. @Transactional
public class YourTest { 
  @Autowired
  private  MenuDao md;
     public void someTest() {     } }

  • When there are multiple test cases, make the above class an abstract one eg->BaseTest.
  • Make all your test classes extend BaseTest (or alternatively, add those annotations on all classes)

A article for Database integration testing / unit-testing with Spring, JPA, JUnit and Maven