Now, onto the geekery, let's take this code example
public class Wheel { public static String defaultBrandName = 'Default Tyres Inc'; public static int defaultSize = 14; public static double defaultPressure = 33; public String brandName; public int size; public double pressure; public Wheel() { this.brandName = defaultBrandName; this.size = defaultSize; this.pressure = defaultPressure; } public Wheel(String brandName, int size, double pressure) { this.brandName = brandName; this.size = size; this.pressure = pressure; } // Some Accessors and Mutators for the instance variables } public class WheelFactory { public static Wheel getWheel() { return new Wheel(); } public static Wheel getCustomWheel(String brandName, int size, double pressure) { return new Wheel(brandName, size, pressure); } }It's quite clear how this now works. We go to the wheel factory and either ask for a default tyre or we specify what kind of tyre we want, as the meerkat says 'Simples'. but what would be the best way to test this to enable me to deploy it to a SDFC production org? Not much I hear you say, but here is an example of the type of thing I have seen.
@isTest public Class WheelFactoryTest { public static testMethod void myUnitTest() { Wheel w = WheelFactory.getWheel(); Wheel w1 = WheelFactory.getWheel('Pirelli', 20, 33); } }And there is it, as far as Force.com is concerned, a perfectly valid unit test! It makes the 75% test coverage requirement and took about 30 seconds to write. Job done! Let me ask you this though, what is my unit 'TEST' actually testing? The simple answer is that it's testing that the WheelFactory and Wheel classes compile and can be called. It's quite frankly a waste of 30 seconds and this test is useless! Is a Wheel being returned? or is it returning a null? What brand is it? What size? What pressure? We just don't know from this test! Below is what I would consider a better test of this:
@isTest public Class WheelFactoryTest { public static testMethod void wheelFactoryGetWheelNoParamsTest() { Wheel w = WheelFactory.getWheel(); System.assert(w != null); System.assert(w.getBrandName() == Wheel.defaultBrandName); System.assert(w.getSize() == Wheel.defaultSize); System.assert(w.getPressure() == Wheel.defaultPressure); } public static testMethod void wheelFactoryGetWheelWithParamsTest() { String brand = "My Brand"; int size = 17; double pressure = 35; Wheel w = WheelFactory.getCustomWheel(brand, size, pressure); System.assert(w.getBrandName() == brand); System.assert(w.getSize() == size); System.assert(w.getPressure() == pressure); }Hopefully you can see the improvements here?
- We are testing each method in a clearly separate way so if one method fails we know instantly which one is broken
- We are using asserts to guarantee that we are getting the correct results! When you see a unit test with no asserts you need to change that! 95% of the time there is no excuse for a unit test with 0 assertions this is testing more than just coverage!
- We are protected from change! Because we are using the static default variables from the WheelFactory class in our tests, if those defaults change our unit test does not need modifying, this is basic coding 101, don't use magic numbers!
- I am actually testing that the tyres are the correct size, pressure and brand! Wouldn't you do that in real life if you were buying tyres for your own car?
No comments:
Post a Comment