2014-01-05 46 views
0

我有類以下類來測試模擬對象。easymock如何模擬/設置公共最終變量

public class FordFulkerson { 

FlowNetwork network; 
Search searchMethod;  

public FordFulkerson (FlowNetwork network, Search method) { 
    this.network = network; 
    this.searchMethod = method; 
} 

public boolean compute() { 
    boolean augmented = false; 
    while (searchMethod.findAugmentingPath(network.vertices)) { 
     processPath(network.vertices); 
     augmented = true; 
    } 
    return augmented; 
} 

protected void processPath(VertexInfo []vertices) { 
    int v = network.sinkIndex; 

    // Determine the amount. Goal is to find the smallest 
    int delta = Integer.MAX_VALUE; 
    while (v != network.sourceIndex) { 
     int u = vertices[v].previous; 

     // Over a forward edge, 
     int flow; 
     if (vertices[v].forward) { 
      flow = network.edge(u, v).capacity - network.edge(u, v).flow; 
     } else { 
      flow = network.edge(v, u).flow; 
     } 

     if (flow < delta) { delta = flow; } 

     v = u; // follow reverse path to source 
    } 

    // push minimal increment over the path 
    v = network.sinkIndex; 
    while (v != network.sourceIndex) { 
     int u = vertices[v].previous; 

     if (vertices[v].forward) { 
      network.edge(u, v).flow += delta; 
     } else { 
      network.edge(v, u).flow -= delta; 
     } 

     v = u; // follow reverse path to source 
    } 

    Arrays.fill(network.vertices, null); // reset for next iteration. 
} 
} 

我的測試:

public class FordFulkersonMockTest { 
private FordFulkerson classUnderTest; 
private FlowNetwork mockNetwork; 
private Search mockSearch; 

@Before 
public void setUp() { 
    mockNetwork = createMock(FlowNetwork.class); 
    mockSearch = createMock(Search.class); 
    classUnderTest = new FordFulkerson(mockNetwork, mockSearch); 

} 

@Test 
public void test01() { 
    expect(mockSearch.findAugmentingPath(null)).andReturn(false); 

    replay(mockSearch); 
    boolean res = classUnderTest.compute(); 
    assertEquals(false, res); 
    verify(mockSearch); 
} 


@Test 
public void test02() { 
    expect(mockSearch.findAugmentingPath(null)).andReturn(true); 
    try{ 
     Field f = mockNetwork.getClass().getDeclaredField("sinkIndex"); 
     f.setAccessible(true); 
     f.set(mockNetwork, 0); 
     f = mockNetwork.getClass().getDeclaredField("sourceIndex"); 
     f.setAccessible(true); 
     f.set(mockNetwork, 0); 
    }catch(Exception e) 
    { 
     fail(e.getMessage()); 
    } 
    replay(mockNetwork); 
    replay(mockSearch); 
    boolean res = classUnderTest.compute(); 
    assertEquals(true, res); 
    verify(mockSearch); 
} 

} 

TEST01工作正常,但在Test02我有問題。 在Test02方法processPath需要被調用。它使用mockNetwork公共最終變量。我不知道在哪裏設置它們。它導致空例外。在代碼中,我試圖改變這個字段的可訪問性,並設置它們,但現在我有錯誤消息「sinkIndex」。

如何模擬mockNetwork中的公共最終變量? Im使用Easymock。

回答

1

你說你修改FlowNetwork的來源,所以你可以做,這將導致更可靠的設計,更容易testablity如下:

  1. 封裝這兩個變量(即private int sinkIndexint getSinkIndex()
  2. expect(mockNetwork.getSinkIndex()).andReturn(0).anyTimes();

猜測:mockNetwork.getClass()正在恢復它沒有狀態(即沒有任何字段)一個CGLIB EasyMock的代理,你可以在調試器檢查。因此getDeclaredField()正在返回null

如果您確實想使用public s,您可以嘗試使用FlowNetwork.class.getDeclaredField

+0

不,我不能改變源代碼。那就是問題所在。我試圖在Test02中改變它們的可訪問性。 – user1736332

+0

啊我看,你只是想'setAccessible',你試過我最後一次編輯嗎?你也可以嘗試不嘲笑網絡,然後'f.set'必須工作。 – TWiStErRob

+0

我需要模擬網絡,它的抽象。我試過了你最後的編輯。 現在我在Arrays.fill(network.vertices,null)有空指針異常; (和沒有改變變量一樣) – user1736332