2015-12-16 26 views
0

我很難測試一個在邏輯中使用生成器模式(BuilderClass)的類(TestClass)。我無法模擬生成器類(BuilderClass)。以下是我的邏輯的簡化版本。無法模擬執行生成器模式

public class TestClass { 
    public int methodA() { 
     ExternalDependency e = BuilerClass.builder().withName("xyz").withNumber(10).build(); 
     return e.callExternalFunction(); 
    } 
} 

這裏是我的生成器類

public class BuilderClass { 
    public static BuilderClass builder() { return new BuilderClass(); } 
    int number; 
    String name; 
    public BuilderClass withName(String name) { 
     this.name = name; 
     return this; 
    } 
    public BuilderClass withNumber(int number) { 
      this.number = number; 
      return this; 
    } 
    public ExternalDependency build() { 
      return new ExternalDependency(name,number); 
    } 
} 

對於我的測試類,我使用的是用的Mockito DataProvider的。

@RunWith(DataProviderRunner.class) 
class TestClassTest { 
@Mock private ExternalDependency e; 
@Mock private BuilderClass b; 
@InjectMocks private TestClass t; 
@Before public void setUp() { MockitoAnnotations.initMocks(this); } 
@Test public void testMethodA() { 
    when(b.withName(any(String.class)).thenReturn(b); //This is not mocking 
    when(b.withNumber(10)).thenReturn(b); //This is not mocking 
    Assert.notNull(this.t.methodA()); //Control while execution is going to implementation of withName and withNumber, which should not happen right. 
    } 

如果我錯過任何東西,請幫助我。由於 }

+2

這不符合你的期望,因爲你嘲笑了模擬的'BuilderClass b'實例上的調用,但'methodA'實際上總是從'BuilerClass.builder'接收到一個全新的,非模擬的'BuilderClass'實例()'調用。 '@InjectMocks'沒有效果,因爲TestClass沒有可注入的依賴關係。一個明顯的建議是將'ExternalDependency'的實例化移到'methodA'之外,以便在測試時注入模擬實例。 – kryger

回答

0

類似於kryger在評論說以上,你可能需要做這樣的重構:

在測試你的類,創建一個縫用假更換e

public class TestClass { 
    public int methodA() { 
     ExternalDependency e = buildExternalDependency("xyz", 10); 
     return e.callExternalFunction(); 
    } 

    protected ExternalDependency buildExternalDependency(String name, int number) { 
      return BuilerClass.builder().withName(name).withNumber(number).build();  
    } 

} 

在測試代碼,重寫測試類取代e用mock和到輸入端驗證與助洗劑:

@RunWith(DataProviderRunner.class) 
    class TestClassTest { 
    @Mock private ExternalDependency e; 
    private TestClass t; 
    @Before public void setUp() { 
     MockitoAnnotations.initMocks(this); 
     t = new TestClass() { 
      @Override 
      protected ExternalDependency buildExternalDependency(String name, int number) { 
       // validate inputs: 
       Assert.assertEquals(10, number); 
       Assert.assertEquals("xyz", name); 
       return e; // provide the mock  
      }  
     } 
    } 

    @Test public void testMethodA() { 
     // TODO: mock behavior of callExternalFunction() here 

      Assert.notNull(this.t.methodA()); 
    } 
} 

您可能想要進一步使用重構將buildExternalDependency()移動到另一個可以模擬並注入TestClass構造函數的類中。