2013-02-23 78 views
2

什麼是最好的辦法,使單元測試,考慮不同的類層次結構,如:單元測試不同的類層次結構

我有一個基類Car和另一個基類Animal

汽車具有派生類VolksWagenFord。 動物有派生類DogCat

您將如何開發在運行時決定要使用哪種對象的測試。 考慮到這些測試將被應用於來自不同層級的數百萬個對象 ,在不使用代碼複製的情況下實現這些測試的最佳方法是什麼?

這是一個面試問題,問我的一個朋友。

+0

想法是測試派生類的基接口嗎?例如,如果'Car'有一個'startEngine()'和一個'engineIsOn()'方法,請確保'engineIsOn()'在調用'startEngine()'後返回'true',無論派生類「車」實際上被使用。 – 2013-02-23 15:02:09

+0

顯示您想要測試的示例。我不明白你的意思。你的意思是你有幾百萬個不同的課程? – 2013-02-23 15:02:53

回答

1

問題,因爲我看到它:避免重複通用測試來驗證n個派生的公共基類型。

  • 創建一個抽象測試夾具。在這裏,您使用抽象方法GetTestSubject()在抽象基類(搜索術語'抽象測試夾具')中針對基類型&編寫測試。此類型的派生將覆蓋返回要測試的類型實例的方法。所以你需要用一個重寫的方法編寫N個子類型,但是你的測試將被寫入一次。
  • 一些像NUnit支持'參數化測試'(搜索術語)的單元測試框架 - 您必須實現一個方法/屬性,該方法/屬性將返回需要運行測試的所有對象。然後它會在運行時對每個這樣的對象運行一次/所有測試。這樣你就不需要編寫N個派生類 - 只有一種方法。
+0

那麼,你的第一個答案就是這樣的? http://weblogs.asp.net/nunitaddin/archive/2004/05/18/134151.aspx – Tito 2013-02-25 16:00:52

+0

@Tito - 完美。 – Gishu 2013-02-26 04:19:07

0

以下是我以前使用過的一種方法(以及此變體)。

讓我們假設你有某種對汽車常用的方法(go),你要測試的所有類,並且在子類中有不同的行爲的一些具體方法(breakDown),即:

public class Car { 
    protected String engineNoise = null; 

    public void go() { 
     engineNoise = "vroom"; 
    } 

    public void breakDown() { 
     engineNoise = null; 
    } 

    public String getEngineNoise() { 
     return engineNoise; 
    } 
} 

public class Volkswagen extends Car { 
    public void breakDown() { 
     throw new UnsupportedOperationException(); 
    } 
} 

然後,你可以定義一個測試如下:

public abstract class CarTest<T extends Car> { 
    T car; 

    @Before 
    public void setUp() { 
     car = createCar(); 
    } 

    @Test 
    public void testVroom() { 
     car.go(); 
     assertThat(car.getEngineNoise(), is("vroom")); 
    } 

    @Test 
    public void testBreakDown() { 
     car.breakDown(); 
     assertThat(car.getEngineNoise(), is(null)); 
    } 

    protected abstract T createCar(); 
} 

現在,由於Volkswagen需要做不同的東西在testBreakDown方法 - 並可能有孃家其他方法d測試 - 然後您可以使用以下VolkswagenTest

public class VolkswagenTest extends CarTest<Volkswagen> { 
    @Test(expected = UnsupportedOperationException.class) 
    public void testBreakdown() { 
     car.breakDown(); 
    } 

    protected Volkswagen createCar() { 
     return new Volkswagen(); 
    } 
} 

希望幫助!

0

其實單元測試方法測試,當你想寫你必須考慮到要編寫和測試方法的功能的單元測試,然後創建類(ES)和方法(s)爲測試那。通過在設計和編寫代碼時考慮這種方法,可能會創建類的層次結構,或者只是單個類或任何類型的其他設計。

但是當你必須使用現有的設計像你上面提到的東西,那麼最好的做法是使用InterfacesBase Classes爲dependecy對象,因爲這樣你可以嘲笑或存根輕易這些類。