As If Unit Testing Mattered
As If Unit Testing Mattered
Problem: How do you gain control over code? Easy in pure code
System
Environment
Environment
Agenda
What do you mean my API has a problem? Dilemmas of API Development Tips and Tricks Language Design to the Rescue? What Are We Protecting, Really?
API Problems
<<returns>>
API Problems
API Problems
protected void Save_Clicked(object sender, EventArgs e) { DataTable table = new DataTable(); table.Columns.Add( new DataColumn("Name", typeof(string))); table.Columns.Add( new DataColumn("Comments", typeof(string))); DataRow row = table.NewRow(); row["Name"] = name.Text; row["Comments"] = comments.Text; table.Rows.Add(row); book.DataSource = table; book.DataBind(); }
API Problems
Banking + getAccountList() : List Account <<returns>> + getOwner() : Owner Owner <<returns>> + getRegistration() : Registration
API Problems
Socket + makeServerSocket() : Socket + getInput() : Stream + bind(address) : void + getPort() : int ...
API Problems
API Dilemmas
Users can misuse APIs (and blame you) Security API development has a high profile
API Dilemmas
Static methods work better if you pull back one extra level of indirection.. Singleton becomes Registry [Fowler]
Registry
public class Registry { private static SettingsProvider settingsProvider = new ProductionSettingsProvider(); public static SettingsProvider getSettings() { return settingsProvider; } public static void setSettingsForTest(SettingsProvider provider) { settingsProvider = provider; } }
Monostate Factory
SocketFactory - serverSocketMaker : ServerSocketMaker - socketMaker : SocketMaker + makeServerSocket() : ServerSocket + makeSocket() : Socket + setServerSocketMakerForTest( :ServerMaker) : void + setSocketMakerForTest( :SocketMaker) : void ... <<interface>> ServerSocketMaker + make() : ServerSocket
10
Handling Mail
MailReciever + MailReceiver( :MessageProcessor, : HostInformation) + getMessageCount(); + checkForMail(); - processMessages( :Message []) - isDeleted( :Message) - getMessages( :Folder) - getSession() : Session - getStore() : Store - getFolder() : Folder # isMessageToRoute( :Message)
11
Supply Interfaces
Interfaces in the broad sense yes, abstract bases can be interfaces The concept of an interface is different in C++, C#, Java, and dynamic languages
12
13
14
Language Rescue
Language Rescue
15
Protection?
You encounter code like this in the middle of an application. Your job is to get the code under control. What do you do?
System.exit(1);
Protection?
Options
Test with a security manager (iffy) Wrap the call and throw an exception
16
Protection?
Madness!
Think of security! Safety! Malicious attacks!
System + setExit(: ExitOperation) + exit( :int) ...
Protection?
In Ruby..
Why is this different?
class Something def do_it exit(1) end end class Something def exit(value) end end # tests ..
17
Protection?
Why are you able to open your electronics? Your car engine?
Protection?
18
Resources
Effective Java Joshua Bloch Framework Design Guidelines Cwalina, Abrams Test Driven Development By Example Kent Beck Working Effectively with Legacy Code Michael Feathers The Eclipse API Rules of Engagement
http://help.eclipse.org/help32/index.jsp?topic=/org.eclipse.platform.doc.isv/referenc e/misc/api-usage-rules.html
19