Saturday, December 29, 2012

Mockito and Spring proxies

I use Spring and I use Mockito. Mockito is extremely good at keeping unit tests fast but of course it is also beneficial to sometimes test by wiring up Spring (integration tests). However, when I do integration tests I sometimes only want to wire up part of the world and mock out other parts. Let me introduce some code before continuing. Say we have this code:

@Component
public class PostDistrictFinder {
 
 public String getDistrict(String letter) {

  // this will involve some complex lookup into an even more complex Cobol
  // based system

  return "SOME DISTRICT";

 }

}



@Component
public class PostCentral {

 @Autowired
 private PostDistrictFinder finder;


 //This is just a plain annotation to force Spring to make a proxy
 @Timed
 public void processLetter(String letter) {

  // process letter, e.g. calculate whether postage is correct or send out
  // invoice, validate address as known etc.

  String district = finder.getDistrict(letter);
  System.err.println(district);

  // forward letter to district

 }

}


public class Main {

 public static void main(final String[] args) {
  final ApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/mock-context.xml");

  final PostCentral bean = context.getBean(PostCentral.class);

  bean.processLetter("");
 }
}
Essentially it is just one bean using another bean. Running this code will print "SOME DISTRICT".

Say I have this test, what do you think it prints?:
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class MockServiceTest {


 @Mock
 private PostDistrictFinder pdf;
 
 
 @Autowired
 @InjectMocks
 private PostCentral poc;

 
 @Before
 public void setup(){
  MockitoAnnotations.initMocks(this);
  Mockito.when(pdf.getDistrict(Mockito.anyString())).thenReturn("Mocked value");
 }
 
 
 @Test
 public void test() throws Exception {

  poc.processLetter("");
  
 }

}
Does it print "SOME DISTRICT" or "Mocked value"? What do you think it prints if you remove the @Timed annotation on the processLetter in the PostCentral class?

Well the above method prints "SOME DISTRICT" and not "Mocked value" with the @Timed annotation on the method and "Mocked value" without the @Timed annotation (note that the result would have been the same had I used @Transactional).

Why is that? The reason is that Spring will create a proxy of the PostCentral class if it is annotated with @Timed (or @Transaction) or any other annotation that causes a proxy to be created. Set a break point in the code and verify if you are in doubt.

How do you get the test to work? You might think that this is enough:
 @Before
 public void setup(){
  MockitoAnnotations.initMocks(this);
  ReflectionTestUtils.setField(poc, "finder", pdf);
  Mockito.when(pdf.getDistrict(Mockito.anyString())).thenReturn("Mocked value");
 
 }
However, this is not the case, as you are operating on the proxy and not the proxied object. You can however do this:


 //REMOVE THE @InjectMocks FROM THE PostCentral (poc) FIELD

 @Before
 public void setup() throws Exception{
  MockitoAnnotations.initMocks(this);
  PostCentral pc = (PostCentral) unwrapProxy(poc);
  ReflectionTestUtils.setField(pc, "finder", pdf);
  Mockito.when(pdf.getDistrict(Mockito.anyString())).thenReturn("Mocked value");
 
 }

 //http://forum.springsource.org/showthread.php?60216-Need-to-unwrap-a-proxy-to-get-the-object-being-proxied
 
 public static final Object unwrapProxy(Object bean) throws Exception {
  
  /*
   * If the given object is a proxy, set the return value as the object
   * being proxied, otherwise return the given object.
   */
  if (AopUtils.isAopProxy(bean) && bean instanceof Advised) {
   
   Advised advised = (Advised) bean;
   
   bean = advised.getTargetSource().getTarget();
  }
  
  return bean;
 }


If the above makes sense, then fine. If you want to understand the inner workings of Spring AOP/proxies, then read this http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-understanding-aop-proxies.

Monday, November 19, 2012

Editing large/big files on linux / cygwin

Have you ever needed to work with and in particular edit very big files? E.g. 400MB+ XML files. Try opening such files in a normal editor and it will most likely complain. I use sed, which is a part of the unix toolchain, to edit such big files. 

How to view a particular line in a large/big file? 

Say you have to view the contents of line 102.000 in a file named tmp.xml. You can do this using sed like this:
sed '100200q;d' tmp.xml

How to change some of the contents of a particular line in a large/big file?

Say you have a file tmp.xml that has encoded & as & instead of & which is the correct way to encode & in XML. You want to change this enconding on line 100. You can you this using sed like this:
sed -e '100s/&/&/' tmp.xml > tmp-modified.xml
The format is linenums/stuff to replace/replacement/ (remember the s after linenum as well as the two /).

Friday, November 9, 2012

Breaking a circular dependency in Spring

Have you ever seen a stack trace like this and wondered what to do:
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanA' defined in file [\BeanA.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [BeanB]: : Error creating bean with name 'beanB' defined in file [\BeanB.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [BeanA]: : Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanB' defined in file [\BeanB.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [BeanA]: : Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?
 at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:730)
...
 at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
 at (Main.java:12)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanB' defined in file [\BeanB.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [BeanA]: : Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?
 at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:730)
...
org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:723)
 ... 15 more
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?
 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:297)
...
Then you probably have code like this:
@Component
public class BeanA {

 private final BeanB beanB;

 @Autowired
 public BeanA(BeanB beanB) {
  this.beanB = beanB;
 }

 @Override
 public String toString() {
  return beanB.getClass().getSimpleName() + " from " + this.getClass().getSimpleName();
 }

}

@Component
public class BeanB {

 private final BeanA beanA;

 @Autowired
 public BeanB(BeanA beanA) {
  this.beanA = beanA;
 }

 @Override
 public String toString() {
  return beanA.getClass().getSimpleName() + " from " + this.getClass().getSimpleName();

 }

}
How do you break such a circular reference in Spring? You could and should consider whether your code could be structured better. However, if you have considered this, then read on to find a way to break the circular reference. Take look at the Provider interface. Then take a look at this code:
@Component
public class BeanA {

 private final Provider<BeanB> beanB;

 @Autowired
 public BeanA(Provider<BeanB> beanB) {
  this.beanB = beanB;
 }

 @Override
 public String toString() {
  return beanB.get().getClass().getSimpleName() + " from " + this.getClass().getSimpleName();
 }

}

@Component
public class BeanB {

 private final Provider<BeanA> beanA;

 @Autowired
 public BeanB(Provider<BeanA> beanA) {
  this.beanA = beanA;
 }

 @Override
 public String toString() {
  return beanA.get().getClass().getSimpleName() + " from " + this.getClass().getSimpleName();

 }

}
If you run this code:
public class Main {

 public static void main(String... args) throws InterruptedException, ExecutionException {

  ApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[] { "META-INF/spring/app-context.xml" });
  BeanA beanA = applicationContext.getBean(BeanA.class);
  BeanB beanB = applicationContext.getBean(BeanB.class);
  System.err.println(beanA);
  System.err.println(beanB);

 }

}
You will see this instead of the above stack trace:
BeanB from BeanA
BeanA from BeanB
Note: the above is just a toy example to illustrate the point. In the code without use of the Provider interface you could actually just delete the constructors and put @Autowired on the Bean* fields (removing the final modifier) and it would work.

Saturday, October 6, 2012

More testing @Transactional

I have written a little about testing @Transactional in the entry Testing @Transactional (a rip off of Chris Beams).

The test he mentions is called transferServiceIsTransactional but the name promises more that it can hold. Judging from the name of the test one could assume that all methods in the transferService are transactional. However, the interface of the bean is this:

public interface TransferService {

  TransferReceipt transfer(double amount, String srcAcctId, String destAcctId)
throws InsufficientFundsException;

  void setMinimumTransferAmount(double minimumTransferAmount);
}

and the implementation is this:

public class DefaultTransferService implements TransferService {

  //Some code...

  @Override
  public void setMinimumTransferAmount(double minimumTransferAmount) {
    //impl
    //NOTE: there is no @Transactional here
  }

  @Override
  @Transactional
  public TransferReceipt transfer(double amount, String srcAcctId, String dstAcctId)
    throws InsufficientFundsException {
    //impl
  }
}

As you can see the implementation only has @Transactional on one of the methods. This of course means that only that one method is transactional - albeit the bean as such is being advised by the TransactionInterceptor.

One could improve the unit test like this to check whether all methods in an interface are in fact transactional:

@Test
public void transferServiceIsNotTransactional() {
  String methodName = null;

  if (AopUtils.isAopProxy(transferService)) {
    for (Advisor advisor : ((Advised) transferService).getAdvisors()) {
      if (TransactionInterceptor.class.equals(advisor.getAdvice().getClass())) {
       TransactionInterceptor ti = (TransactionInterceptor) advisor.getAdvice();
        for (Method method : TransferService.class.getMethods()) {
          TransactionAttribute transactionAttribute = 
          ti.getTransactionAttributeSource()
          .getTransactionAttribute(method, AopUtils.getTargetClass(transferService));
          if (transactionAttribute == null) {
            methodName = method.getName();
            break;
          }
        }
      }
    }
  }
  assertNull("not all methods in transferService are transactional: ["
    + methodName + "]", methodName);
 }


In all fairness to Chris Beams it should be stated that the code I have commented on above was not the topic of the talk for which he wrote it. So, this is not a critique of the very good seminar.

Friday, September 14, 2012

Spring @Async

I'll give a short demo a Spring's @Async annotation. Observe the following class (which is a Spring component):

@Component
public class SpringAsyncService {
 
 @Async
 public void writeSomethingASync() throws InterruptedException{
 
  System.err.println("Async start");

  Thread.sleep(10000);
  
  System.err.println("Async end");
 }

 @Async
 public Future<String> writeSomethingASyncResult() throws InterruptedException{
 
  System.err.println("Async with result start");
  
  Thread.sleep(10000);
  
  System.err.println("Async with result end");
  return new AsyncResult<String>("Returning from async with result");
 }


 public void writeSomethingSync(){
  System.err.println("Sync");
 }

}
The class has three methods of which the first two have the @Async annotation. Now observer the following class:

public class Main {

    public static void main(String... args) throws InterruptedException, ExecutionException {

     ApplicationContext applicationContext = new ClassPathXmlApplicationContext(new String[] {
       "META-INF/spring/app-context.xml"});
     SpringAsyncService service = applicationContext.getBean(SpringAsyncService.class);
     
     Future<String> f = service.writeSomethingASyncResult();
     service.writeSomethingASync();
     service.writeSomethingSync();
     System.err.println(f.get());
         
    }
}
The above writes out the following (note that "Sync" is done before the async methods, even though it is called last):
Async with result start
Sync
Async start
Async end
Async with result end
Returning from async with result
If we put the System.err.println(f.get()) line right after the call to writeSomethingASyncResult then the output will be (as the main thread is waiting for the result of the asynchronous method):
Async with result start
Async with result end
Returning from async with result
Sync
Async start
Async end

Here is the configuration file. The important stuff is the task namespace and the annotation-driven tag:
<?xml version="1.0" encoding="UTF-8"?>
<beans 
xmlns="http://www.springframework.org/schema/beans"
xmlns:task="http://www.springframework.org/schema/task" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans  
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
http://www.springframework.org/schema/context  
http://www.springframework.org/schema/context/spring-context-3.0.xsd 
http://www.springframework.org/schema/task 
http://www.springframework.org/schema/task/spring-task-3.0.xsd">

 <context:component-scan base-package="org.saabye_pedersen.spring" />

 <task:annotation-driven />

</beans>

Sunday, June 10, 2012

Testing @Transactional

Do you use Spring? Then chances are that you use @Transactional in your code.

@Transactional is very clever, but would it not be smart if some unit test failed if someone accidentally removed the @Transactional annotation?

In the code for the seminar Spring Dependency Injection Styles the author Chris Beams has this unit test:

As you can see this method will test whether the transferService implementation (being injected further up the test class) is transactional by checking whether it is being advised by the TransactionInterceptor (consult the Spring documentation on transactions if you are unsure about why this makes sense).

Smart!

Sunday, April 29, 2012

Enabling specifications and Scrum


Obtaining a patent

To obtain a patent in the US, one thing you have to do is make a specification:

The specification must include a written description of the invention and of the manner and process of making and using it, and is required to be in such full, clear, concise, and exact terms as to enable any person skilled in the technological area to which the invention pertains, or with which it is most nearly connected, to make and use the same (Specification [Description and Claims]).

In other words, the specification should be complete in the sense that by reading it, people skilled in the subject matter, should be able to make whatever the specification specifies - without needing any further clarification.

Scrum and enabling specifications

Jeff Sutherland, one of the fathers of Scrum, has written that:

requirements are NOT enabling specifications

Why is that? Image that you develop some online service and then think of the requirement "The user should be authenticated to the use the service". Is the requirement a full, clear and concise specification? Or might you have questions like a) how should the user be authenticated (e.g. username/password)? b) when should authentication commence (e.g. at every interaction or perhaps a some gate guarding some parts of the service)? c) should the service automatically log the user out after some period of inactivity? The questions are many and only one person can answer them, the Product Owner.

Jeff Sutherland continues:

A user story must be an enabling specification for agile teams to operate at peak performance. If it is not, there will be the need for continued dialogue with the Product Owner during the sprint to figure out what the story means. This will reduce story process efficiency and cripple velocity.

[T]he documentation needed, including transcribing all the conversations, should be on the order of 3-5 pages for a moderately large feature


All Jeff Sutherland quotes come from: Enabling Specifications: The Key to Building Agile Systems.


Emergent requirement

The above sound good, but isn't Scrum all about emergent requirements and specifications? That is, isn't the nature of software that we can only have a full, clear and concise specification when we are done. The Enabling Specification Scrum pattern says:

Most schedule surprises come from lapses in analysis. Since estimation focuses on what happens within the sprint, it's important to move the uncertainty of analysis outside the sprint — into the Product Owner process. If you don't do this, the developers end doing analysis. That greatly slows velocity, and because the team is not expert in analysis or end-user and market perspectives, the requirements suffer as well.

Therefore: The Product Owner should deliver enabling specifications as a sign that he or she has done due diligence in exploring the requirements space.

The claim is not that the Product Owner alone should do all analysis up front. He can work with the team, other business people, customers and so on. But the analysis has to be done and the product backlog items are the responsibility of the PO.