@Test
public void writeToShouldSerializeRequestsFormParamBinariesValuesAndTextValuesWithAppropriateSerializer() throws Exception {

    Param p1 = mock(Param.class);
    Param p2 = mock(Param.class);
    Param p3 = mock(Param.class);
    ParamConfig paramConfig1 = mock(ParamConfig.class);
    ParamConfig paramConfig2 = mock(ParamConfig.class);
    ParamConfig paramConfig3 = mock(ParamConfig.class);
    List<Param> params = asList(p1,p2,p3);
    Request request = mock(Request.class);
    MethodConfig methodConfig = mock(MethodConfig.class);
    when(request.getParams(ParamType.FORM)).thenReturn(params);
    when(request.getMethodConfig()).thenReturn(methodConfig);
    when(methodConfig.getCharset()).thenReturn(UTF8);
    when(p1.getParamConfig()).thenReturn(paramConfig1);
    when(p2.getParamConfig()).thenReturn(paramConfig2);
    when(p3.getParamConfig()).thenReturn(paramConfig3);
    when(paramConfig1.getValueClass()).thenReturn((Class)String.class);
    when(paramConfig2.getValueClass()).thenReturn((Class) InputStream.class);
    when(paramConfig3.getValueClass()).thenReturn((Class) File.class);
    final AtomicReference<MultiPart<Param>> mp1 = new AtomicReference<MultiPart<Param>>();
    final AtomicReference<MultiPart<Param>> mp2 = new AtomicReference<MultiPart<Param>>();
    final AtomicReference<MultiPart<Param>> mp3 = new AtomicReference<MultiPart<Param>>();
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    doAnswer(new Answer() {
        public Object answer(InvocationOnMock invocation) throws Throwable {
            ((DataOutputStream)invocation.getArguments()[2]).writeBytes("t1\r\n");
            mp1.set((MultiPart)invocation.getArguments()[0]);
            return null;
        }
    }).when(mockMultiPartTextSerializer).serialize(isA(MultiPart.class), eq(UTF8), isA(DataOutputStream.class));
    doAnswer(new Answer() {
        int i = 0;
        public Object answer(InvocationOnMock invocation) throws Throwable {
            if(i++ == 0) {
                ((DataOutputStream)invocation.getArguments()[2]).writeBytes("b1\r\n");
                mp2.set((MultiPart)invocation.getArguments()[0]);
            }else{
                ((DataOutputStream)invocation.getArguments()[2]).writeBytes("b2\r\n");
                mp3.set((MultiPart)invocation.getArguments()[0]);
            }
            return null;
        }
    }).when(mockMultiPartBinarySerializer).serialize(isA(MultiPart.class), eq(UTF8), isA(DataOutputStream.class));
    toTest.writeTo(request, out);
    assertEquals("t1\r\n" +
            "b1\r\n" +
            "b2\r\n" +
            "--"+mp2.get().getBoundary()+"--\r\n\r\n", out.toString());
    assertEquals(mp1.get().getBoundary(), mp2.get().getBoundary());
    assertEquals(mp1.get().getBoundary(), mp3.get().getBoundary());
    assertTrue(mp1.get().getBoundary().matches("[a-zA-Z0-9]{24}"));
    assertSame(paramConfig1, mp1.get().getParamConfig());
    assertSame(p1, mp1.get().getValue());
    assertSame(paramConfig2, mp2.get().getParamConfig());
    assertSame(p2, mp2.get().getValue());
    assertSame(paramConfig3, mp3.get().getParamConfig());
    assertSame(p3, mp3.get().getValue());
}