Recent Posts

How do you like your Mocks served?

2 minute read

I like them refreshing, of course:

Mockito is the new Java mock library on the block, with lots of interesting features. It replaced JMock in almost all my Java projects, mainly because:- the syntax produces_ clear and readable test code_ (see below for an example), because it doesn’t abuse of anonymous class and methods are really methods.

  • stub and verification happens logically, and at different place
  • no replay or framework control methods ala EasyMock
  • fully integrated to Junit (using @RunWith for instance)
  • helpful annotations to create mock automagically
  • it promotes simple tests by nature (and that’s essential to my eyes)

Basically, you can only do two things with Mockito:

  • stub, or
  • verify :-)

Enough discussion, let’s focus on an example:

@Test
public void itShouldComputeAndSetThePlayerRank() 
{  
  // creating a mock from an interface  
  // is as easy as that:  
  Player p = mock(Player.class)  
  
  // stub a method  
  when(p.getScore()).thenReturn(5);  
  
  // our imaginary SUT  
  ELOCalculator.computeRank(p);  
  
  // let's verify our rank has been computed  
  verify(p).setRank(12);
}

Due to its use of Generics and Java 5 autoboxing, the syntax is very clean, clear and readable. But that’s not all, Mockito provide a Junit 4 runner that simplifies mock creation with the help of annotations:

@RunWith(MockitoJUnit44Runner.class)
public class OurImaginaryTestCase
{  
  @Mock
  private Player player;  
  
  @Test  
  public void playerShouldBeRanked()  
  {     
    // we can use player directly here,     
    // it is mocked to the Player Interface  
  }
}

Of course during the verification phase of the test you can check for

  • the number of calls (or check for no calls at all)
  • the arguments (Mockito defines lots of useful arguments matcher, and you can plug any Hamcrest matchers),
  • the call order,
  • and for stubbing, you can also throw exception, return values, or define callbacks that will be called when a return value is needed.

In a word it’s really powerful. It is also possible to spy on concrete objects however as the manual says this is not partial mocking:

so you can’t use this method to check that the method under test calls other methods of the same object.Here’s an example of what I mean (the following test passes):

public class RealObject 
{
  public int a() 
  { 
    return 10; 
  } 
  
  public int b() 
  { 
    return 20 + a(); 
  }
}

@Test
public final void test1()
{ 
  RealObject real = new RealObject(); 
  RealObject spy = spy(real);
  when(spy.a()).thenReturn(12); 
  
  // notice the 30 here 
  assertThat(spy.b(), equalTo(30));
}

See Mockito author’s last blog post about the subject or this mockito mailing list post.

Basically the code should be refactored or we could use a subclass to overcome this.

There is also a debate about stubbing and verifying (the same call). Usually you don’t want to do that. Stubbing should be enough, if your code succeed then the call was implicitly verified. So usually if you stub there is no need to verify, and if you verify you don’t need to stub (except if you need to return something critical to the rest of the code, in which case you don’t need verification). Once again, Mockito’s author has a great post on the_stubbing or verifying debate_.

Of course if you are an Eclipse user, do not forget to add to the list of Favorites all Mockito static import, so that Content Assist knows all the matchers.

Happy unit testing with Mockito :-)

Net-Snmp doesn’t detect interface speed on Linux

less than 1 minute read

Have you ever wondered why net-snmp doesn’t report a ccomments: true orrect interface speed on Linux?

I was also wondering, until this morning…

I tried to run net-snmp as root, and miracle, the right interface speed was detected for my interfaces. In fact net-snmp uses the SIOCETHTOOL ioctl to access this information. Unfortunately the get settings variant of this ioctl needs to have the CAP_NET_ADMINenabled.

Of course root has this capability set, but when net-snmp drops its privileges to an unprivileged user, this capability is lost and the ioctl fails with EPERM.

That’s too bad because getting this information is at most harmless and shouldn’t require special privileges to succeed.

Someone even posted a Linux Kernel patch to remove CAP_NET_ADMIN check for SIOCETHTOOL which doesn’t seem to have been merged.

The fix could also be on the snmpd side before dropping privileges.

The workaround is to tell net-snmp how the interface are looking:

interface eth0 6 10000000
interface eth1 6 100000000

Here I defined eth0 as a 100mbit/s FastEthernet interface, and eth1 as a GigabitEthernet interface.

OpenNMS JDBC Stored Procedure Poller with MySQL

1 minute read

Since a few months we are monitoring our infrastructure at Days of Wonder with OpenNMS. Until this afternoon we were running the beta/final candidate version 1.5.93.

We are monitoring a few things with the JDBC Stored Procedure Poller, which is really great to monitor complex business operations without writing remote or GP scripts.

Unfortunately the migration to OpenNMS 1.6.1 led me to discover that the JDBC Stored Procedure poller was not working anymore, crashing with a NullPointerException in the MySQL JDBC Driver while trying to fetch the output parameter.

In fact it turned out I was plain wrong. I was using a MySQL PROCEDURE:

DELIMITER //
CREATE PROCEDURE `check_for_something`()
READS SQL DATA
BEGIN
 SELECT ... as valid FROM ...
END
//

But this OpenNMS poller uses the following JDBC procedure call:

{ 
  ? = call check_for_something()
}

After a few struggling, wrestling, and various MySQL JDBC Connector/J driver upgrades, I finally figured out what the driver was doing: The driver rewrites the call I gave above to something like this:

SELECT check_for_something();

This means that the procedure should in fact be a SQL FUNCTION.

Here is the same procedure rewritten as a FUNCTION:

DELIMITER //
CREATE FUNCTION `check_for_something`()
RETURNS int(11)
READS SQL DATA
DETERMINISTIC
BEGIN
  DECLARE valid INTEGER;
  SELECT ... INTO valid FROM ...RETURN valid;
END
//

It now works. I’m amazed it even worked in the first place with 1.5.93 (it was for sure).