MultiPartEntityWriter implements EntityWriter { public void writeTo(Request request, OutputStream outputStream) throws Exception { DataOutputStream out = new DataOutputStream(outputStream); List<Param> formParams = request.getParams(FORM); Charset charset = request.getMethodConfig().getCharset(); for (Param param: formParams) { ParamConfig pc = param.getParamConfig(); Class<?> paramClass = pc.getValueClass(); MultiPart<Param> multiPart = new MultiPart<Param>(pc, param, BOUNDARY); if(MultiPartBinarySerializer.isBinary(paramClass)) { binarySerializer.serialize(multiPart, charset, out); }else{ textSerializer.serialize(multiPart, charset, out); } } out.writeBytes(FULL_BOUNDARY + "--" + LRLN); out.writeBytes(LRLN); out.flush(); } MultiPartEntityWriter();   MultiPartEntityWriter(Serializer<MultiPart<Param>> binarySerializer, Serializer<MultiPart<Param>> textSerializer); String getContentType(Request request); int getContentLength(Request request); void writeTo(Request request, OutputStream outputStream);  }
@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()); }