View Javadoc
1   package com.opencsv.bean;
2   
3   import com.opencsv.TestUtils;
4   import com.opencsv.bean.exceptionhandler.ExceptionHandlerIgnore;
5   import com.opencsv.bean.exceptionhandler.ExceptionHandlerIgnoreThenThrowAfter;
6   import com.opencsv.bean.exceptionhandler.ExceptionHandlerQueueThenThrowAfter;
7   import com.opencsv.bean.mocks.AnnotatedMockBeanFull;
8   import com.opencsv.exceptions.CsvDataTypeMismatchException;
9   import com.opencsv.exceptions.CsvException;
10  import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
11  import org.apache.commons.lang3.tuple.ImmutablePair;
12  import org.junit.jupiter.api.DisplayName;
13  import org.junit.jupiter.api.Test;
14  
15  import java.io.*;
16  import java.nio.file.FileSystems;
17  import java.nio.file.Files;
18  import java.util.LinkedList;
19  import java.util.List;
20  
21  import static org.junit.jupiter.api.Assertions.*;
22  
23  public class ExceptionHandlerTest {
24  
25      /**
26       * Tests reading with an non-standard exception handler.
27       * <p>Also incidentally tests:</p>
28       * <ul>
29       * <li>The "ignore" exception handler</li>
30       * </ul>
31       *
32       * @throws IOException Never
33       */
34      @Test
35      public void testReadWithExceptionHandler() throws IOException {
36          CsvToBean<AnnotatedMockBeanFull> ctb = new CsvToBeanBuilder<AnnotatedMockBeanFull>(new FileReader("src/test/resources/testinputcase7.csv"))
37                  .withSeparator(';')
38                  .withType(AnnotatedMockBeanFull.class)
39                  .withExceptionHandler(new ExceptionHandlerIgnore())
40                  .build();
41          List<AnnotatedMockBeanFull> beans = ctb.parse();
42          assertNotNull(beans);
43          assertTrue(beans.isEmpty());
44          List<CsvException> exceptions = ctb.getCapturedExceptions();
45          assertNotNull(exceptions);
46          assertTrue(exceptions.isEmpty());
47      }
48  
49      @Test
50      public void testLambdaExceptionHandler() throws IOException {
51          final String testString = "test";
52          CsvToBean<AnnotatedMockBeanFull> ctb = new CsvToBeanBuilder<AnnotatedMockBeanFull>(new FileReader("src/test/resources/testinputcase7.csv"))
53                  .withSeparator(';')
54                  .withType(AnnotatedMockBeanFull.class)
55                  .withExceptionHandler(e -> {
56                      throw new CsvException(testString);
57                  })
58                  .build();
59          try {
60              ctb.parse();
61              fail("CsvException should have been thrown.");
62          } catch (RuntimeException re) {
63              assertTrue(re.getCause() instanceof CsvException);
64              CsvException csve = (CsvException) re.getCause();
65              assertEquals(testString, csve.getMessage());
66          }
67      }
68  
69      @Test
70      public void testReadWithQueueThenThrowHandler() throws IOException {
71          BufferedReader inFile = Files.newBufferedReader(FileSystems.getDefault().getPath("src/test/resources/testinputcase85.csv"));
72          String goodLine = inFile.readLine();
73          String badLine = inFile.readLine();
74          inFile.close();
75          StringBuilder sb = new StringBuilder();
76          for (int i = 0; i < 5; i++) {
77              sb.append(badLine);
78              sb.append('\n');
79              for (int j = 0; j < 9; j++) {
80                  sb.append(goodLine);
81                  sb.append('\n');
82              }
83          }
84          MappingStrategy<AnnotatedMockBeanFull> strategy = new ColumnPositionMappingStrategy<>();
85          strategy.setType(AnnotatedMockBeanFull.class);
86          CsvToBean<AnnotatedMockBeanFull> ctb = new CsvToBeanBuilder<AnnotatedMockBeanFull>(new StringReader(sb.toString()))
87                  .withSeparator(';')
88                  .withMappingStrategy(strategy)
89                  .withExceptionHandler(new ExceptionHandlerQueueThenThrowAfter(3))
90                  .build();
91          try {
92              ctb.parse();
93              fail("CsvException should have been thrown.");
94          } catch (RuntimeException re) {
95              assertTrue(re.getCause() instanceof CsvException);
96              CsvException csve = (CsvException) re.getCause();
97              assertEquals(1, csve.getLineNumber() % 10);
98              List<CsvException> capturedExceptions = ctb.getCapturedExceptions();
99              assertNotNull(capturedExceptions);
100             assertFalse(capturedExceptions.isEmpty(), "Expected exceptions in the captured exceptions but there were none.");
101         }
102     }
103 
104     /**
105      * Tests writing with a non-standard exception handler.
106      * <p>Also incidentally tests:</p>
107      * <ul>
108      * <li>The "ignore then throw" exception handler.</li>
109      * </ul>
110      *
111      * @throws IOException                  Never
112      * @throws CsvDataTypeMismatchException Never
113      */
114     @DisplayName("Test ExceptionHandlerIgnoreThenThrowAfter when the max number of exceptions is less than the actual number of exceptions.")
115     @Test
116     public void testWriteWithIgnoreExceptionHandlerSmallNumberOfExceptions() throws IOException, CsvDataTypeMismatchException {
117         ImmutablePair<AnnotatedMockBeanFull, AnnotatedMockBeanFull> beans = TestUtils.createTwoGoodBeans();
118         AnnotatedMockBeanFull goodBean = beans.left;
119         AnnotatedMockBeanFull badBean = beans.right;
120         badBean.setDateDefaultLocale(null); // required field
121         StringWriter w = new StringWriter();
122         MappingStrategy<AnnotatedMockBeanFull> strategy = new ColumnPositionMappingStrategy<>();
123         strategy.setType(AnnotatedMockBeanFull.class);
124         StatefulBeanToCsv<AnnotatedMockBeanFull> b2csv = new StatefulBeanToCsvBuilder<AnnotatedMockBeanFull>(w)
125                 .withMappingStrategy(strategy) // so there is no header for assertFalse(w.toString().isEmpty())
126                 .withExceptionHandler(new ExceptionHandlerIgnoreThenThrowAfter(3))
127                 .build();
128         List<AnnotatedMockBeanFull> inputBeans = new LinkedList<>();
129         for (int i = 0; i < 5; i++) {
130             inputBeans.add(badBean);
131             for (int j = 0; j < 9; j++) {
132                 inputBeans.add(goodBean);
133             }
134         }
135         try {
136             b2csv.write(inputBeans);
137             fail("CsvRequiredFieldEmptyException should have been thrown.");
138         } catch (CsvRequiredFieldEmptyException csve) {
139             // TODO: If we ever implement a separate thread for writing while
140             //  beans are being converted to string, we should add a test:
141             //  assertFalse(w.toString().isEmpty());
142             assertEquals(1, csve.getLineNumber() % 10);
143             List<CsvException> capturedExceptions = b2csv.getCapturedExceptions();
144             assertNotNull(capturedExceptions);
145             assertFalse(capturedExceptions.isEmpty());
146         }
147     }
148 
149     /**
150      * Tests writing with a non-standard exception handler.
151      * <p>Also incidentally tests:</p>
152      * <ul>
153      * <li>The "queue then throw" exception handler.</li>
154      * </ul>
155      *
156      * @throws IOException                  Never
157      * @throws CsvDataTypeMismatchException Never
158      */
159     @DisplayName("Test ExceptionHandlerIgnoreThenThrowAfter when the max number of exceptions is greater than the actual number of exceptions.")
160     @Test
161     public void testWriteWithIgnoreExceptionHandlerLargeMaxExceptions() throws IOException, CsvDataTypeMismatchException, CsvRequiredFieldEmptyException {
162         ImmutablePair<AnnotatedMockBeanFull, AnnotatedMockBeanFull> beans = TestUtils.createTwoGoodBeans();
163         AnnotatedMockBeanFull goodBean = beans.left;
164         AnnotatedMockBeanFull badBean = beans.right;
165         badBean.setDateDefaultLocale(null); // required field
166         StringWriter w = new StringWriter();
167         MappingStrategy<AnnotatedMockBeanFull> strategy = new ColumnPositionMappingStrategy<>();
168         strategy.setType(AnnotatedMockBeanFull.class);
169         StatefulBeanToCsv<AnnotatedMockBeanFull> b2csv = new StatefulBeanToCsvBuilder<AnnotatedMockBeanFull>(w)
170                 .withMappingStrategy(strategy) // so there is no header for assertFalse(w.toString().isEmpty())
171                 .withExceptionHandler(new ExceptionHandlerIgnoreThenThrowAfter(10))
172                 .build();
173         List<AnnotatedMockBeanFull> inputBeans = new LinkedList<>();
174         for (int i = 0; i < 5; i++) {
175             inputBeans.add(badBean);
176             for (int j = 0; j < 9; j++) {
177                 inputBeans.add(goodBean);
178             }
179         }
180 
181         b2csv.write(inputBeans);
182         List<CsvException> capturedExceptions = b2csv.getCapturedExceptions();
183         assertNotNull(capturedExceptions);
184         assertTrue(capturedExceptions.isEmpty());
185     }
186 
187     /**
188      * Tests writing with a non-standard exception handler.
189      * <p>Also incidentally tests:</p>
190      * <ul>
191      * <li>The "queue then throw" exception handler.</li>
192      * </ul>
193      *
194      * @throws IOException                  Never
195      * @throws CsvDataTypeMismatchException Never
196      */
197     @DisplayName("Test ExceptionHandlerQueueThenThrowAfter when the max number of exceptions is less than the actual number of exceptions.")
198     @Test
199     public void testWriteWithQueueExceptionHandlerSmallNumberOfExceptions() throws IOException, CsvDataTypeMismatchException {
200         ImmutablePair<AnnotatedMockBeanFull, AnnotatedMockBeanFull> beans = TestUtils.createTwoGoodBeans();
201         AnnotatedMockBeanFull goodBean = beans.left;
202         AnnotatedMockBeanFull badBean = beans.right;
203         badBean.setDateDefaultLocale(null); // required field
204         StringWriter w = new StringWriter();
205         MappingStrategy<AnnotatedMockBeanFull> strategy = new ColumnPositionMappingStrategy<>();
206         strategy.setType(AnnotatedMockBeanFull.class);
207         StatefulBeanToCsv<AnnotatedMockBeanFull> b2csv = new StatefulBeanToCsvBuilder<AnnotatedMockBeanFull>(w)
208                 .withMappingStrategy(strategy) // so there is no header for assertFalse(w.toString().isEmpty())
209                 .withExceptionHandler(new ExceptionHandlerQueueThenThrowAfter(3))
210                 .build();
211         List<AnnotatedMockBeanFull> inputBeans = new LinkedList<>();
212         for (int i = 0; i < 5; i++) {
213             inputBeans.add(badBean);
214             for (int j = 0; j < 9; j++) {
215                 inputBeans.add(goodBean);
216             }
217         }
218         try {
219             b2csv.write(inputBeans);
220             fail("CsvRequiredFieldEmptyException should have been thrown.");
221         } catch (CsvRequiredFieldEmptyException csve) {
222             // TODO: If we ever implement a separate thread for writing while
223             //  beans are being converted to string, we should add a test:
224             //  assertFalse(w.toString().isEmpty());
225             assertEquals(1, csve.getLineNumber() % 10);
226             List<CsvException> capturedExceptions = b2csv.getCapturedExceptions();
227             assertNotNull(capturedExceptions);
228             assertFalse(capturedExceptions.isEmpty());
229             assertTrue(capturedExceptions.size() >= 3);
230             assertTrue(capturedExceptions.contains(csve));
231         }
232     }
233 
234     /**
235      * Tests writing with a non-standard exception handler.
236      * <p>Also incidentally tests:</p>
237      * <ul>
238      * <li>The "ignore then throw" exception handler.</li>
239      * </ul>
240      *
241      * @throws IOException                  Never
242      * @throws CsvDataTypeMismatchException Never
243      */
244     @DisplayName("Test ExceptionHandlerQueueThenThrowAfter when the max number of exceptions is greater than the actual number of exceptions.")
245     @Test
246     public void testWriteWithQueueExceptionHandlerLargeMaxExceptions() throws IOException, CsvDataTypeMismatchException, CsvRequiredFieldEmptyException {
247         ImmutablePair<AnnotatedMockBeanFull, AnnotatedMockBeanFull> beans = TestUtils.createTwoGoodBeans();
248         AnnotatedMockBeanFull goodBean = beans.left;
249         AnnotatedMockBeanFull badBean = beans.right;
250         badBean.setDateDefaultLocale(null); // required field
251         StringWriter w = new StringWriter();
252         MappingStrategy<AnnotatedMockBeanFull> strategy = new ColumnPositionMappingStrategy<>();
253         strategy.setType(AnnotatedMockBeanFull.class);
254         StatefulBeanToCsv<AnnotatedMockBeanFull> b2csv = new StatefulBeanToCsvBuilder<AnnotatedMockBeanFull>(w)
255                 .withMappingStrategy(strategy) // so there is no header for assertFalse(w.toString().isEmpty())
256                 .withExceptionHandler(new ExceptionHandlerQueueThenThrowAfter(10))
257                 .build();
258         List<AnnotatedMockBeanFull> inputBeans = new LinkedList<>();
259         for (int i = 0; i < 5; i++) {
260             inputBeans.add(badBean);
261             for (int j = 0; j < 9; j++) {
262                 inputBeans.add(goodBean);
263             }
264         }
265 
266         b2csv.write(inputBeans);
267         List<CsvException> capturedExceptions = b2csv.getCapturedExceptions();
268         assertNotNull(capturedExceptions);
269         assertFalse(capturedExceptions.isEmpty());
270         assertEquals(5, capturedExceptions.size());
271     }
272 
273     @Test
274     public void testQueueThenThrowExceptionHandler() throws IOException, CsvDataTypeMismatchException {
275         ImmutablePair<AnnotatedMockBeanFull, AnnotatedMockBeanFull> beans = TestUtils.createTwoGoodBeans();
276         AnnotatedMockBeanFull goodBean = beans.left;
277         AnnotatedMockBeanFull badBean = beans.right;
278         badBean.setDateDefaultLocale(null); // required field
279         StringWriter w = new StringWriter();
280         MappingStrategy<AnnotatedMockBeanFull> strategy = new ColumnPositionMappingStrategy<>();
281         strategy.setType(AnnotatedMockBeanFull.class);
282         StatefulBeanToCsv<AnnotatedMockBeanFull> b2csv = new StatefulBeanToCsvBuilder<AnnotatedMockBeanFull>(w)
283                 .withMappingStrategy(strategy) // so there is no header for assertFalse(w.toString().isEmpty())
284                 .withExceptionHandler(new ExceptionHandlerQueueThenThrowAfter(3))
285                 .build();
286         List<AnnotatedMockBeanFull> inputBeans = new LinkedList<>();
287         for (int i = 0; i < 5; i++) {
288             inputBeans.add(badBean);
289             for (int j = 0; j < 9; j++) {
290                 inputBeans.add(goodBean);
291             }
292         }
293         try {
294             b2csv.write(inputBeans);
295             fail("CsvRequiredFieldEmptyException should have been thrown.");
296         } catch (CsvRequiredFieldEmptyException csve) {
297             // TODO: If we ever implement a separate thread for writing while
298             //  beans are being converted to strings, we should add a test:
299             //  assertFalse(w.toString().isEmpty());
300             assertEquals(1, csve.getLineNumber() % 10);
301             List<CsvException> capturedExceptions = b2csv.getCapturedExceptions();
302             assertNotNull(capturedExceptions);
303             assertFalse(capturedExceptions.isEmpty());
304         }
305     }
306 }