1

I must covered whit Junit4 and Mockito/PowerMockito the While Block and the catch block. The Exception StateException is launched by the getHrest method

public class Fstate{
 ….
private Date selectedDate;
private Date dateYes;
private Collection<State> sStateList;
private boolean statePlus;
private String stateVisibility;

@EJB
private Muller mull;
….
public void methodState(){
    final Calendar calendar=new GregorianCalendar();
    this.dateYes=calendar.getTime();
    this.selectedDate = this.dateYes;
    Collection<State> allState=null;
    try{
        allState=this.mull.getHrest(this.p, this.b, this.ba, this.so);
        Iterator<State> iter=allState.iterator();
        while(iter.hasNext()){
            State s=iter.next();
            String s_string=s.getSfielString(); 
            this.sStateList.add(s_string);
        }
     } catch (StateException stateException){
        WebLogger.fatal(stateException.getMessage(), LOGGER_OUT);
    }
    this.statePlus=loadStatePlus(this.dateYes);
    this.stateVisibility=STATE_PLUS;
}
}

Below, in the first method I want to cover the while execution while in the second method I want to cover the catch. However, this does not generate the expected result, while block and catch not covered!

@Test
public void state_Test(){
    try {
    
        Fstate spyFstate = Mockito.spy(Fstate.class);
        
        State mockState=Mockito.mock(Muller.class);     
        
        Mockito.when(mockState.getHrest(anyString(), anyString(), anyString(), anyString())).thenReturn(createCollectionOfStates());
        Whitebox.setInternalState(spyFstate, "mull",mockState);
        
        spyFstate.methodState();
        Mockito.verify(spyFstate, Mockito.times(1)).methodState();
        
    } catch (StateException e) {
        System.out.println("StateException in state_Test method!");
    }
}
    
@Test
public void stateException_Test(){
    try {
            Fstate spyFstate = Mockito.spy(Fstate.class);
            
            State mockState=Mockito.mock(Muller.class); 
    
            Mockito.when(mockState.getHrest(anyString(), anyString(), anyString(), anyString())).thenThrow(new StateException("StateException Exception"));
            
            Whitebox.setInternalState(spyFstate, "mull",mockState);
            spyFstate.methodState();
            
            Mockito.verify(spyFstate, Mockito.times(1)).methodState();
            
    } catch (DealAnagException e) {
            e.printStackTrace();
    }   
}

Dep
  • 11
  • 4
  • Note: the *real* answer might be to further dissect your code. Instead of defining the list in the method, to then iterate the list in that method, and update an internal list ... why not have a helper method that just takes a list, and returns a list? You can test that completely on its own, without ANY mocking? And unrelated: floow java naming conventions. `s_string` is sooo wrong, and nothing-telling. Use names that follow conventions, and that tell the reader what the thing they name are about. – GhostCat Jul 26 '21 at 15:15
  • So, long story short: your production code is overly complicated, and if you would follow the "clean code" principles ... you would end up with code that would also be much easier to test. That is why people to TDD: when you do tests AFTER you wrote your production code, you risk to end up with **hard to test** code. And then you need all kinds of complicated "work arounds" in your test code to make up for that. Overly complicated production code leads to overly complicated test code. Which means you just doubled the amount of hard to read / understand code. – GhostCat Jul 26 '21 at 15:17

2 Answers2

0

I think you just have to instantiate your Fstate before creating your spy like this :

Fstate fstate = new Fstate();
Fstate spyFstate = Mockito.spy(fstate);
Julien Gavard
  • 613
  • 1
  • 6
  • 20
0

I solved this by help of the comments of GhostCat.

Quote:

Note: The real answer might be to further dissect your code. Instead of defining the list in the method to then iterate the list in that method, and update an internal list, why not have a helper method that just takes a list, and returns a list? You can test that completely on its own, without ANY mocking?

And unrelated: flow java naming conventions. s_string is sooo wrong, and says nothing about what the variable is for. Use names that follow conventions and that tell the reader what they are about.

So, long story short: Your production code is overly complicated and if you would follow the "clean code" principles, you would end up with code that would also be much easier to test. That is why people to TDD: When you do tests AFTER you write your production code, you risk ending up with hard-to-test code. And then you need all kinds of complicated "work arounds" in your test code to make up for that. Overly complicated production code leads to overly complicated test code. Which means you just doubled the amount of hard-to-read/understand code.

ouflak
  • 2,458
  • 10
  • 44
  • 49
Dep
  • 11
  • 4