How to simulate caught and logged exceptions inside a method and create JUnit tests

我只是一个虾纸丫 提交于 2019-12-24 09:17:11

问题


I have to write JUnit test cases for existing code where I do not have the liberty / opportunity to re-write the actual code. In many of these classes, the methods catch an exception internally and just log it. And the exceptions are not based on any parameters which could be manipulated to attempt to throw the exception, but are thrown by the code inside the method - e.g. - the method may open a file and catch IOException and just log it. Basically, many of the methods just eat all the possible exceptions - which I know is very bad practice, but at this point in time, we have to continue with it.

Is it possible to have code coverage for such situations. Since the classes have a lot of such constructs, it keeps the code coverage of the class very low and I have to get the coverage to at least 75%

I have tried different things found from different examples but none of them have worked.

UPDATE

Adding an example of the code for which I need to add JUnit tests.

    public StringBuilder getTxtFiles(InputStream in) {
        StringBuilder out = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        String line;
        try {
            while ((line = reader.readLine()) != null) {
                out.append(line);
            }
        } catch (IOException e) {
            System.out.println("Error Occurred ");
            e.printStackTrace();
        }
        return out;
    }

This is just an example. There are different kinds of object creations with "new" and different exceptions thrown. What I need is an example of writing a JUnit test that will provide coverage for catch clauses of this type.

Update 2 - Another Example

Class to be tested

  package com.test.model;

  import com.datastax.driver.core.LocalDate;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.cassandra.core.PrimaryKeyType;
  import org.springframework.data.annotation.Transient;
  import org.springframework.data.cassandra.mapping.Column;
  import org.springframework.data.cassandra.mapping.PrimaryKeyColumn;
  import org.springframework.data.cassandra.mapping.Table;

  import javax.persistence.Entity;
  import java.io.Serializable;
  import java.text.SimpleDateFormat;
  import java.time.Instant;
  import java.util.Calendar;
  import java.util.Date;
  import java.util.GregorianCalendar;

  @Entity
  @Table("test_master")
  public class TestMaster implements Serializable {
     private static final Logger LOGGER = LoggerFactory.getLogger(TestMaster.class);
     private static final long serialVersionUID = 1L;

      @PrimaryKeyColumn(name = "test_number", ordinal = 0, type = PrimaryKeyType.PARTITIONED)
      private String testNumber;

      @Column(value = "test_requested_date")
      private LocalDate testRequestedDate;

      @Column(value = "transfer_date")
      private LocalDate transferDate;

      public LocalDate getTestRequestedDate() {
          return testRequestedDate;
      }

      public void setTestRequestedDate(LocalDate testRequestedDate) {
          this.testRequestedDate = testRequestedDate;
      }

      public void setOtherAppTestRequestedDate(String otherAppTestRequestedDate) {
          this.otherAppTestRequestedDate = otherAppTestRequestedDate;
      }

      public void setOtherAppTestTransferdate(String otherAppTestTransferdate) {
          this.otherAppTestTransferdate = otherAppTestTransferdate;
      }

      @Transient
      private String otherAppTestRequestedDate;

      @Transient
      private String otherAppTestTransferdate;

      public static Date subtractDays(Date date, int days) {
          GregorianCalendar cal = new GregorianCalendar();
          cal.setTime(date);
          cal.add(Calendar.DATE, -days);
          return cal.getTime();
      }

      public String getTestNumber() {
          return testNumber;
      }

      public void setTestNumber(String loanNumber) {
          this.testNumber = testNumber;
      }

      public String getOtherAppTestRequestedDate() {
          String ourformat ="";
          LOGGER.info("getTestRequestedDate()--->"+getTestRequestedDate());
          try {
              if (getTestRequestedDate() != null && getTestRequestedDate().getMillisSinceEpoch() > 0) {
                  Date d = new Date(getTestRequestedDate().getMillisSinceEpoch());
                  SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
                  ourformat = formatter.format(d.getTime());
                  System.out.println("getOtherAppTestRequestedDate()--->" + ourformat);
              }
          }catch(Exception e){
              e.printStackTrace();
          }
          return ourformat;
      }

      public LocalDate getTransferDate() {
          return transferDate;
      }
      public void setTransferDate(LocalDate transferDate) {
          this.transferDate = transferDate;
      }

      public  String getOtherAppTestTransferdate(){
          String ourformat = "";
          LOGGER.info("TranferDate"+getTransferDate());
          SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
          SimpleDateFormat stringFormatter = new SimpleDateFormat("yyyyMMdd");
          try {
              if (getTransferDate() != null && getTransferDate().getMillisSinceEpoch() > 0) {
                  ourformat= getTransferDate().toString();
                  Date date1=format.parse(ourformat);
                  ourformat=stringFormatter.format(date1);
                  System.out.println("printing getIdeaTransferdate" + ourformat);
              }
          }catch(Exception e){
              e.printStackTrace();
          }
          return ourformat;
      }

  }

Sample JUnit test Class

  package com.test.model;

  import com.datastax.driver.core.LocalDate;
  import org.junit.Assert;
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.mockito.InjectMocks;
  import org.powermock.api.mockito.PowerMockito;
  import org.powermock.core.classloader.annotations.PowerMockIgnore;
  import org.powermock.core.classloader.annotations.PrepareForTest;
  import org.powermock.modules.junit4.PowerMockRunner;
  import org.powermock.modules.junit4.PowerMockRunnerDelegate;
  import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

  import java.text.ParseException;
  import java.text.SimpleDateFormat;

  import static org.mockito.Matchers.anyString;
  import static org.powermock.api.mockito.PowerMockito.when;

  @RunWith(PowerMockRunner.class)
  @PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
  @PrepareForTest({SimpleDateFormat.class})
  @PowerMockIgnore("javax.management.*")
  public class TestMasterTest {

      @InjectMocks
      TestMaster model;

      @Test
      public void testGetIdeaTransferdateException() throws ParseException {
          SimpleDateFormat sdfMock = PowerMockito.mock(SimpleDateFormat.class);
          PowerMockito.when(sdfMock.parse(anyString())).thenThrow(new ParseException("Exception cause", 1));
          model.setTransferDate(LocalDate.fromYearMonthDay(2018, 1, 3));
          when(model.getTransferDate()).thenReturn(null);
          // Tried this with anyString() instead of null
          // also tried with "when" clause above the model.setTransfer clause
          Assert.assertEquals("20180103",model.getOtherAppTestTransferdate());
          Assert.assertNotNull("Expected date : 20180103",model.getOtherAppTestTransferdate());
      }
  }

This is the error I get

  org.mockito.exceptions.misusing.MissingMethodInvocationException: 
  when() requires an argument which has to be 'a method call on a mock'.
  For example:
      when(mock.getArticles()).thenReturn(articles);
  Or 'a static method call on a prepared class`
  For example:
      @PrepareForTest( { StaticService.class }) 
      TestClass{
         public void testMethod(){
             PowerMockito.mockStatic(StaticService.class);
             when(StaticService.say()).thenReturn(expected);
         }
      }

  Also, this error might show up because:
  1. inside when() you don't call method on mock but on some other object.
  2. inside when() you don't call static method, but class has not been prepared.



     at org.powermock.api.extension.reporter.MockingFrameworkReporterFactoryImpl$PowerMockitoReporter.missingMethodInvocation(MockingFrameworkReporterFactoryImpl.java:66)
     at com.test.model.TestMasterTest.testGetIdeaTransferdateException(TestMasterTest.java:35)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.lang.reflect.Method.invoke(Method.java:498)
     at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
     at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
     at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
     at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
     at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
     at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
     at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
     at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
     at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
     at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
     at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
     at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
     at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner$2.call(DelegatingPowerMockRunner.java:148)
     at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner$2.call(DelegatingPowerMockRunner.java:140)
     at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner.withContextClassLoader(DelegatingPowerMockRunner.java:131)
     at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner.run(DelegatingPowerMockRunner.java:140)
     at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:121)
     at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
     at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
     at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
     at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
     at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
     at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
     at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

  2018-09-13 08:29:03.368-0400   INFO o.s.c.support.GenericApplicationContext   Closing org.springframework.context.support.GenericApplicationContext@61c9c3fd: startup date [Thu Sep 13 08:29:00 EDT 2018]; root of context hierarchy

How can I achieve this?

Thank you

来源:https://stackoverflow.com/questions/52267168/how-to-simulate-caught-and-logged-exceptions-inside-a-method-and-create-junit-te

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!