java - How to handle ordering of @Rule's when they are dependent on each other -
i use embedded servers run inside junit test cases. these servers require working directory (for example apache directory server).
the new @rule in junit 4.7 can handle these cases. temporaryfolder-rule can create temporary directory. custom externalresource-rule can created server. how handle if want pass result 1 rule another:
import static org.junit.assert.assertequals; import java.io.*; import org.junit.*; import org.junit.rules.*; public class folderruleorderingtest { @rule public temporaryfolder folder = new temporaryfolder(); @rule public mynumberserver server = new mynumberserver(folder); @test public void testmynumberserver() throws ioexception { server.storenumber(10); assertequals(10, server.getnumber()); } /** simple server can store 1 number */ private static class mynumberserver extends externalresource { private temporaryfolder folder; /** actual datafile number stored */ private file datafile; public mynumberserver(temporaryfolder folder) { this.folder = folder; } @override protected void before() throws throwable { if (folder.getroot() == null) { throw new runtimeexception("temporaryfolder not initialized"); } //all server data stored working folder file workingfolder = folder.newfolder("my-work-folder"); datafile = new file(workingfolder, "datafile"); } public void storenumber(int number) throws ioexception { datafile.createnewfile(); dataoutputstream out = new dataoutputstream(new fileoutputstream(datafile)); out.writeint(number); } public int getnumber() throws ioexception { datainputstream in = new datainputstream(new fileinputstream(datafile)); return in.readint(); } } }
in code folder sent parameter server server can create working directory store data. not work because junit processes rules in reverse order defined in file. temporaryfolder rule not executed before server rule. root-folder in tempraryfolder null, resulting files created relative current working directory.
if reverse order of attributes in class compile error because cannot reference variable before defined.
i'm using junit 4.8.1 (because ordering of rules fixed bit 4.7 release)
edit: released junit 4.10, can use @rulechain chain rules correctly (see @ end).
you introduce private field without @rule annotation, can reorder code wish:
public class folderruleorderingtest { private temporaryfolder privatefolder = new temporaryfolder(); @rule public mynumberserver server = new mynumberserver(privatefolder); @rule public temporaryfolder folder = privatefolder; @test public void testmynumberserver() throws ioexception { server.storenumber(10); assertequals(10, server.getnumber()); } ... }
the cleanest solution have compound rule, above should work.
edit: released junit 4.10, can use rulechain
chain rules correctly:
public static class userulechain { @rule public testrule chain= rulechain .outerrule(new loggingrule("outer rule")) .around(new loggingrule("middle rule")) .around(new loggingrule("inner rule")); @test public void example() { asserttrue(true); } }
writes log
starting outer rule starting middle rule starting inner rule finished inner rule finished middle rule finished outer rule
Comments
Post a Comment