I just now started using junit/unit tests facilities. And now I feel what goodness it is :) Is it possible to print field values if a junit test fails?
My method try implement INT(A(D — B)^C):
public static int countFieldEventPoints(PointsCountingTableRow row,float centimetres){
float temp = row.getA()*(float)Math.pow((centimetres - row.getB()),row.getC());
return roundUP(temp);
}
My test:
public void testCountlongJumpEventPoints(){
PointsCountingTableRow row = Tables.get2001table().getLongJump();
float cm = 736f;
assertEquals(900,PointCounterService.countFieldEventPoints(row,cm));
}
console print:
java.lang.AssertionError:
Expected :900
Actual :901
round up method (I feel there is the problem):
private static int roundUP(double floatNumber){
return (int) Math.round(floatNumber + .5);
}
row class:
public class PointsCountingTableRow {
private float A;
private float B;
private float C;
public PointsCountingTableRow(float a, float b, float c) {
A = a;
B = b;
C = c;
}
public float getA() {
return A;
}
public float getB() {
return B;
}
public float getC() {
return C;
}
}
Welcome to the wonderful world of Unit Testing :) For the sake of code covering, it's a good practice to code a set of test methods for each public method in your API: one for each interesting case, including successful and failing tests (thanks to Florian Schaetz).
What to do then, whith private methods (as roundUP) ? They also deserve a test battery, which you can easily design after a simple refactorizing of your API:
Create a new "helper" class with package (default) access, and a private constructor. This class will contain just public static methods.
Move roundUP from its actual container class to the helper class, and make it public.
Create a public tester class, in the same package (thus granting it access to the helper class), and fullfil it with the necessary testing methods.
Back to your case, you can code several testing methods to benchmark roundUP properly: I suggest ten methods: roundUP(0.0), roundUP(0.1), roundUP(0.2) ... roundUP(0.9).
As part of the Test Driven Development, every time a new error in your program is reported, you must then code a new tester method to reproduce such an error. Then, fix the bug until all the testers work OK (the new and the existing ones): In this way the test battery will grow and make sure that no updates nor fixes will accidentally break the existing behaviour.
Is it possible to print row fields values if test fall?
Of corse. You can program your testing methods to react in case of fail, in this way:
#Test
public void myTest()
{
// Prepare the input parameters:
PointsCountingTableRow row=...
float centimetres=...
// Perform the test:
int result=countFieldEventPoints(row, centimeters);
// Check the results:
String messageInCaseOfFail="row="+row.toString();
assertEquals(messageInCaseOfFail, expectedResult, result);
}
Or also through the fail methd:
#Test
public void myTest()
{
// Prepare the input parameters:
...
// Perform the test:
try
{
int result=countFieldEventPoints(row, centimeters);
// Check the results:
assert...
}
catch (SomeException e)
{
fail(messsageInCaseOfFail);
}
}
Is it possible to print field values if a test fails?
Of course it is. However, I wouldn't recommend doing that. Instead, if a unit test fails, and you can't see why it is happening by looking at the code, then I would recommend that you do the following:
run the failing test in your IDE's debugger,
set a breakpoint at the appropriate point, and
use the debugger UI to examine the state of the objects and variables directly.
I'd only implement diagnostic (e.g. display) code in a unit test suite in particularly complicated cases.
Adding diagnostic code to a unit test only increases the volume of code that needs to be read and maintained. Besides, it is only necessary for a test that fails ... and that is a scenario that you are aiming to eliminate.
Related
Suppose I have a code like below
public boolean checkForecastIfCityRaining(String name){
result = WeatherAPICallToSomeVendor(name)
if(result = rain)return true; else return false;
}
How would I unit test if the result data will change depending
on what the API vendor is providing?
Would i mock a fixed result of every scenario and then unit test
it like so?
A UNIT test should really only test a single method at a time (Isolate other functionality that might be invoked by that method). My current group might achieve that by writing our function like this:
public class WeatherCheck
{
private ForecastService fs;
public WeatherCheck(ForecastService fs)
{
forecastService = fs;
}
public boolean checkForecastIfCityRaining(String name){
result = forecastService.weatherAPICallToSomeVendor(name)
if(result = rain)return true; else return false;
}
This would allow us to pass a mock forecast service into the constructor. Dependency Injection would be better, but we don't do that yet.
Note: We differentiate between a Unit test and an Integration test. We still might write our Integration tests with Junit, but they have more of a tendency to go out and actually poke the service--this can give you advance warning of a failure. So you might write an integration test for ForecastService that simply calls the weatherAPICallToSomeVendor method of ForecastService and ensures a non-error result (Perhaps no exceptions or doesn't return null...).
I think the function needs to be rewritten as this:
public boolean checkForecastInCityCondition(String city, String condition){
result = WeatherAPICallToSomeVendor(city)
return result == condition;
}
Now you gain the advantage of exposing clients to care about arbitrary conditions and you can enhance with a new API as needed. From a testing perspective you can now safely write tests like this:
public void testRainingInLancaster() throws Exception{
//your code here
}
public void testSnowInRedding() throws Exception{
//your code here
}
And you can determine which pieces need to be mocked for testing.
I have a class that I am trying to unit test. This class extends another class that I am not interested in unit testing at this time.
The following code is an over simplification of the code I am trying to test.
package com.example.somePackage;
public class ApiBase {
protected <T extends SomeClass> t getApi(Class<T> apiClass) {/* some logic*/}
}
package com.example.anotherPackage;
public MagicApiImpl extends ApiBase {
private final MagicApiHandler apiHandler = new MagicApiHandler();
public String doSomeStuff(String someString) {
final BookApi bookApi = getApi(BookApi.class);
// some logic
return apiHandler.someMethod(bookApi, someString);
}
}
I would like to test doSomeStuff() on MagicApiImpl The part I would like to mock is what comes back in getApi().
At first go I tried simply creating an Instance of MagicApiImpl and setting all the behind the scenes things that happen but that started to become over complex for the scenario I want to test and the number of times I need to test it in other classes. I will handle the testing of the logic in getApi() in a test of its own.
It would be helpful to use EasyMock to test this as it is what a majority of the tests for this project are written in but I would not be overly apposed to using mockito.
Edit
Okay I was reading about the Mockito.spy() That would have been wonderful but sadly getApi is protected and in another package. Worst case I could fall back on placing all the tests in that package but that makes it difficult track code.
Using Easymock partial mocks your test should look like this:
#Test
public void test() {
MagicApiImpl impl = EasyMock.createMockBuilder(MagicApiImpl.class)
.addMockedMethod("getApi")
.createMock();
EasyMock.expect(impl.getApi(BookApi.class)).andReturn(/**Wharever you need*/);
EasyMock.replay(impl);
String input = "INPUT";
String output = impl.doSomeStuff(input);
System.out.println("The OUTPUT is: " + output);
EasyMock.verify(impl);
//Run asserts here
}
Reference: http://easymock.org/user-guide.html#mocking-partial
I'm trying to write a unit test for a function that has a condition for wifi state. When the wifi state is disconnected, the function returns with false, but I want to simulate a scenario when the wifi state is connected. How do I go about it? Should I make a setter for the state variable? Isn't that a bad approach?
The function I want to test:
public boolean performSomething() {
if (WIFI_STATE != "connected") {
return false;
}else{
....
}
}
I want to test the else part of the function above, but as you may have guessed, the function executes the if condition, and returns false because WIFI_STATE is "disconnected"
Without seeing any of your code, make sure your class uses a WifiState constructor parameter or injection (or something similar). In your test you can then provide a mock for this object and set the state accordingly to your testing needs.
Two approaches that I can think of:
1: Define a sensor's state capturing class say WifiStatus, which your production code initializes automatically through a static initializer.
For testing, you can load a dummy WifiStatus class though a test initializer or change the value of WifiStatus through instrumentation.
2: Use WifiStatus as a interface and then mock it for dependency injection. This approach is more common.
public interface WifiStatus{
boolean isConnected();//
}
public class Performer{
WifiStatus wifiStatusProvider;
public Performer(WifiStatus stateProvider){
this.wifiStatusProvider = stateProvider;
}
public boolean performSomething() {
//if (WIFI_STATE != "connected") {
if (wifiStatusProvider.isConnected() != true) {
return false;
}else{
....
}
}
}
For test class, you use as follows:
public class PerformerTest{
#Test
public void verifyPerformSomething(){
WifiStatus dummyWifiStatus = mock(WifiStatus.class);
doReturn(true).when(dummyWifiStatus).isConnected();
new Performer(dummyWifiStatus).performSomething();
}
}
Assuming you are talking about "Local Unit Tests" and not "Instrumented Unit Tests", you can use Robolectric: http://robolectric.org
http://robolectric.org/javadoc/3.0/org/robolectric/shadows/ShadowWifiManager.html
https://github.com/robolectric/robolectric/blob/master/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiManagerTest.java
Local Unit Tests:
https://developer.android.com/training/testing/unit-testing/instrumented-unit-tests.html
Instrumented Unit Tests:
https://developer.android.com/training/testing/unit-testing/instrumented-unit-tests.html
Well, for testing, you must be sure for your input how your output looks like because you need to compare them. Make the boolean value of wifi state is injected from outside, so you can mock it how you like. For example:
public boolean method(boolean wifiState){
return !wifiState;
}
So now you can be sure that if your parameter is false you will got true and vice versa so you can mock that param and make your tests.
Chiming in with a code-based answer based on john16384's answer. You mention that the state is set with other functions within the same class, assuming those methods are public I propose something like this (assuming WifiChecker is your class):
private WifiChecker wifiChecker;
#Before public void setUp() {
wifiChecker = new WifiChecker();
}
#Test public void testWifiConnected() {
wifiChecker.setConnected()
assertTrue(wifiChecker.performSomething());
}
#Test public void testWifiDisconnected() {
wifiChecker.setDisconnected()
assertFalse(wifiChecker.performSomething());
}
Let's say I have the following classes in the respective source folders/packages...
[src/myApp]
|_Employee «concrete»
|_Manager «abstract»
|_ManagerImpl «concrete» (Class Under Test)
|_Recruiter «abstract»
|_RecruiterImpl «concrete» (Collaborator)
...
public class ManagerImpl implements Manager {
...
private Recruiter recR;
...
public void growTeam( Object criteria ){
//...check preconditions
Employee newB = recR.srcEmployee( criteria );
//...whatever else
}
...
}
...
[test/myApp]
|_RecruiterStandIn «concrete»
|_ManagerImplTest
...
public class RecruiterStandIn implements Recruiter {
Map<Object, Employee> reSrcPool = new HashMap<>();
public RecruiterStandIn( ){
// populate reSrcPool with dummy test data...
}
public Employee srcEmployee( Object criteria ){
return reSrcPool.get( criteria );
}
}
...
public class ManagerImplTest {
...
// Class Under Test
private ManagerImpl mgr;
// Collaborator
private Recruiter recR = new RecruiterStandIn( );
...
public void testGrowTeam( ) {
//...
mgr.setRecruiter( recR );
mgr.growTeam( criteria );
// assertions follow...
}
...
}
...
Here are my questions: Given that I have a RecruiterStandIn concrete implementation that already exists within the codebase for testing purposes (in the test scope)...
Would it be redundant to also use a mock in the above unit test?
What would be the value (if any) in additionally doing something like this in the above unit test?
...
...
#Mock
private Recruiter recR;
...
...
public void testGrowTeam( ) {
...
expect( recR.srcEmployee( blah) ).andReturn( blah )...
// exercising/assertions/validations as usual...
}
...
You can safely assume that RecruiterStandIn does everything the class under test will ever require of it for the purposes of the above unit test. That is to say, for the sake of simple answers/explanations, there's no need to overcomplicate the above scenario with contrived what-ifs around maintenance of the stub and whatnot.
Thanks in advance.
My answers to your specific questions:
Would it be redundant to also use a mock in the above unit test?
As the unit test is written right now it would be redundant but my see answer to your second question below.
What would be the value (if any) in additionally doing something like this in the above unit test?
It think this is the way you should be doing your tests and I would recommend getting rid of your stub, RecruiterStandIn. Instead I would setup the recruit to return canned answers so you don't have to maintain two classes just to return some predefined data:
#Spy
private Recruiter recR;
public void testGrowTeam( ) {
// Setup canned data return
doReturn(generateTestEmployee()).when(recR).srcEmployee(any(Object.class));
expect( recR.srcEmployee( blah) ).andReturn( blah )...
// exercising/assertions/validations as usual...
}
FYI the above syntax would be for using Mockito. From what I can tell in your case Mockito gives you the power of stubbing out certain parts and much more without requiring you to create new test entities.
Original Answer
Definitely yes you should be doing mock object tests. Mocks Aren't Stubs. Mock object testing allows you to test the interactions between your classes and ensure that things are interacting with the world around them correctly. I think there is less value in these tests when you first write the classes and their corresponding tests. Mock object tests shine a year down the road when a new developer comes in and inadvertently your breaks code because she didn't understand that certain internal behavior was needed..
A somewhat contrived example would be if let's say we had a Car that needed to fill up some gas:
public class Car {
public void fuelUp()
}
Now with standard unit tests we would check that after calling fuelUp() the car was full of gas and that the proper amount of money was deducted from the driver. But since we never tested how fuelUp() was interacting with the world around it, it could easily be doing the following:
public void fueldUp() {
siphonGasFromNearestCar();
buyCoffeeAndChips()
}
But with mock object testing you can ensure that the Car is getting filled up in the proper and expected way.
For public method calls, EasyMock's capture() allows you to intercept & examine arguments passed to the method. For private method calls, PowerMock's expectPrivate lets you mock private method calls.
Is there a way to somehow combine these and get the arguments passed to a private method call? Example:
public class Program
{
public FancyReturnType PublicMethod()
{
ArbitraryType localInstance = new ArbitraryType();
localInstance.setFoo(somePrivateHelperMethod());
localInstance.setBar(increasinglyComplexMagic());
long aLongValue = 11235L;
// more variables, more work
SomeType worker = privateHelperToIntercept(localInstance, aLongValue, otherVariables);
if (worker.something)
{
return retVal.aFancyReturnType;
}
else
{
return retVal.anotherFancyReturnType;
}
}
}
In this case, I want to examine the localInstance object as it is consumed by the privateHelperToIntercept() call.
I've found plenty of examples to mock private method calls; PowerMock's expectPrivate(partiallyMockedObject, "nameOfPrivateMethod", arg1, arg2) works great. I've also found examples to intercept arguments passed to public method calls; Capture<Type> myTestCapture = new Capture<Type>() combined with someMockedObject.PublicMethod(capture(myTestCapture)).
Unfortunately, I can neither get the two to work together, nor find examples of combining them. Has anyone seen a way to do this?
FWIW, I suspect Mockito can do this, but it's not included in our source/build/test system. I'd like to avoid the process of supporting new libraries in our system if possible.
If you are asking how to get a reference to localInstance, then the following code should suffice.
#PrepareForTest(Program.class)
public class Test {
#Test
public void testMethod() {
ArbitraryType passedLocalInstance = new ArbitraryType();
PowerMock.expectNew(ArbitraryType.class).andReturn(passedLocalInstance );
//remainder of the test method
assertEquals(14.2, passedLocalInstance .getValue());
}
}
Since java is pass-by-reference, the passedLocalInstance will be the argument passed into the method call. Did that answer your question?
new of any type is simply a static method. Deal with it in the same way... wrap it in a method, stub out the method. In this case you want to return a mock in your test, and then you can test all the interactions with that object (and remove dependency in your test on the code within the object you are creating which should have it's own tests)
public Program {
// your above code up to object creation
ArbitraryType localInstance = createArbitraryType();
// rest of your above code here
ArbitraryType createArbitraryType() {
return new ArbitraryType();
}
}
in your test...
public class MyTest {
TestableProgram extends Program {
#Override
ArbitraryType createArbitraryType() {
return this.arbitraryTypeMock;
}
}
private ArbitraryType arbitraryTypeMock;
private TestableMyClass objectToTest = new TestableProgram();
// rest of your tests...
}
Given your constraint's that's how I'd do it.
If could bend your constraints a bit I'd loosen up on the private methods, I've generally done away with private in favor of package default to make testing easier. If the folks IN your package are misbehaving, it's usually your code so private is mostly protecting you from yourself anyway. (but I know that isn't a valid answer your question as posed... ).