url - How can I write test driven java class for download manager? -
i developing download manager using design.in elaboration iteration, main use case:download file.here download.java
public class download implements runnable { // max size of download buffer. private static final int max_buffer_size = 1024; // these status names. public static final string statuses[] = {"downloading", "complete"}; // these status codes. public static final int downloading = 0; public static final int complete = 1; public static void main(string[] args) throws malformedurlexception { system.out.println("welcome download manager."); system.out.println("enter url."); url url; string s; scanner scan= new scanner(system.in); s=scan.nextline(); url= new url(s); download download=new download(url); } private url url; // download url private int size; // size of download in bytes private int downloaded; // number of bytes downloaded private int status; // current status of download // constructor download. public download(url url) { this.url = url; size = -1; downloaded = 0; status = downloading; // begin download. download(); } // start or resume downloading. private void download() { system.out.println("starting."); thread thread = new thread(this); thread.start(); } // download file. public void run() { randomaccessfile file = null; inputstream stream = null; try { // open connection url. httpurlconnection connection = (httpurlconnection) url.openconnection(); // specify portion of file download. connection.setrequestproperty("range", "bytes=" + downloaded + "-"); // connect server. connection.connect(); int contentlength = connection.getcontentlength(); /* set size download if hasn't been set. */ if (size == -1) { size = contentlength; } // open file , seek end of it. file = new randomaccessfile(getfilename(url), "rw"); file.seek(downloaded); stream = connection.getinputstream(); while (status == downloading) { /* size buffer according how of file left download. */ byte buffer[]; if (size - downloaded > max_buffer_size) { buffer = new byte[max_buffer_size]; } else { buffer = new byte[size - downloaded]; } system.out.print("%"+(downloaded/size)+'\r'); // read server buffer. int read = stream.read(buffer); if (read == -1){ system.out.println("file downloaded"); break; } // write buffer file. file.write(buffer, 0, read); downloaded += read; } /* change status complete if point reached because downloading has finished. */ if (status == downloading) { status = complete; } } catch (exception e) { system.out.println("error!"); } { // close file. if (file != null) { try { file.close(); } catch (exception e) {} } // close connection server. if (stream != null) { try { stream.close(); } catch (exception e) {} } } } how can write test code of code?for example should test url verifying,or should control whether file downloading or not?how can these tests? thanks.
the class you've written difficult test because it's trying much. if extract of responsibilities external dependencies, end 1 class manage low-level downloading urls , manage local filesystem. like:
interface urldownloader { inputstream download(url url, int offset) throws ioexception; } interface downloadfolder { list<string> getfiles(); void writetofile(string filename, inputstream contents) throws ioexception; void getfilesize(string filename); } the download manager can tested mocked versions of these classes. library mockito, can write test like:
@test public void candownloadcompletefile() throws ioexception { url url = new url("http://example.com/file.txt"); inputstream inputstream = new bytearrayinputstream("abc".getbytes()); urldownloader urldownloader = mock(urldownloader.class); downloadfolder downloadfolder = mock(downloadfolder.class); when(urldownloader.download(url, 0)).thenreturn(inputstream); downloadmanager manager = new downloadmanager(urldownloader, downloadfolder); manager.download(url); verify(downloadfolder).writetofile("file.txt", inputstream); } with mockito can control when dependencies throw exceptions, or verify methods called specific parameters.
another way create fake classes implement interfaces , use in-memory data structures instead of real filesystem/network. state of these classes can tested assertequals etc:
@test public void candownloadcompletefile() throws ioexception { url url = new url("http://example.com/file.txt"); fakedownloadfolder downloadfolder = new fakedownloadfolder(); fakeurldownloader urldownloader = new fakeurldownloader(); urldownloader.seturlcontents(url, "abc".getbytes()); downloadmanager manager = new downloadmanager(urldownloader, downloadfolder); manager.download(url); assertequals("abc".getbytes(), downloadfolder.getfileasbytearray("file.txt")); } the idea behind test-driven development write code backed tests. you'd implement enough of downloadmanager pass first test, , add test (resume incomplete download, example).
Comments
Post a Comment