Let's assume we have third-party service implementation to mock. If service was designed well, it implements some kind of interface (or interfaces) so clients could call different methods using interface contracts.
package com.example; import java.util.Collection; public interface SimpleService { Collection< String > getServiceProviders(); Collection< String > getServiceProviders( final String regex ); }The simplest and beautiful test case will look like this:
package com.example import org.junit.Test class SimpleServiceTestCase extends GroovyTestCase { @Test void testGetServiceProvidersByPattern() { // Create implementation from a map, method name : implementation (closure) def simpleService = [ getServiceProviders : { String regex -> [ "Provider 1", "Provider 2" ] } ] as SimpleService assertEquals( [ "Provider 1", "Provider 2" ], simpleService.getServiceProviders( "Provider*" ) ) } }Awesome and easy! Let's consider another use case: service has implementation only, no interfaces. Could we mock and it as well? Yes!
package com.example; public class SimpleServiceImpl { public Collection< String > getServiceProviders() { return null; } public Collection< String > getServiceProviders( final String regex ) { return null; } }The test case is a bit more verbose because of using Groovy mocking framework. You can also specify how many calls you expect as well as call sequences.
package com.example import groovy.mock.interceptor.MockFor import org.junit.Test import com.example.impl.SimpleServiceImpl class SimpleServiceTestCase extends GroovyTestCase { @Test void testGetServiceProviders() { def context = new MockFor( SimpleServiceImpl ) context.demand.with { getServiceProviders() { -> [ "Provider 1", "Provider 2" ] } } context.use { def simpleService = new SimpleServiceImpl() assertEquals( [ "Provider 1", "Provider 2" ], simpleService.getServiceProviders() ) } } }Cool and easy! The obvious question is, what about mocking static methods? You will love Groovy after that (as I do). Let's complicate our service a bit with static method.
package com.example; public class SimpleServiceImpl { public static Collection< String > getDefaultServiceProviders() { return null; } // Other methods here }So the test case for mocking this static method is no more than one line of code (thanks to Groovy meta-programming capabilities):
package com.example class SimpleServiceTestCase extends GroovyTestCase { @Test void testGetDefaultServiceProviders() { SimpleServiceImpl.metaClass.'static'.getDefaultServiceProviders = { -> [ "Provider 1", "Provider 2" ] } assertEquals( [ "Provider 1", "Provider 2" ], SimpleServiceImpl.getDefaultServiceProviders() ) } }And that's it!
No comments:
Post a Comment