2016-05-17 78 views
1

考慮下面的「生產」代碼:如何將@Injectable Class對象應用於@Tested類的構造函數?

public class Foo<T extends Number> { 

    private Bar delegate; 
    private Class<T> numberClass; 

    public Foo(Class<T> numberClass) { 
     this.numberClass = numberClass; 
    } 

    public T doSomething() { 
     if (numberClass==Integer.class) { 
      return delegate.getIntValue(); 
     } else if (numberClass==Float.class) { 
      return delegate.getFloatValue(); 
     } else if (numberClass==Double.class) { 
      return delegate.getDoubleValue(); 
     } // etc etc etc 
     return null; 
    } 
} 

這是基於我現在面臨一個真實的情況......我沒有對委託對象的實現沒有控制權。

那麼,我該如何使用JMockit @Tested註釋來測試這個類?我無法使用@Injectable注入Class值...它抱怨Class不可嘲笑。我不想嘲笑它,只是注入它。與字符串或基元或枚舉不同,在那裏我可以說@Injectable("foobar") String s;並獲得一個非模擬注入對象,這些語義不適用於Class對象。

顯然,我的解決方法是手動構建我的Foo@Before方法,所以我會。但我不禁覺得這種情況應該可以通過JMockit來實現。

回答

1

總之,你不能使用@Tested,因爲jmockit不會讓你模擬Class類。你會寫你的測試是這樣的:

@Test 
public void testDoSomethingWithInteger(@Mocked final Bar bar) { 
    final int expectedValue = 10; 

    new NonStrictExpectations() { 
     { 
      bar.getIntValue(); 
      result = expectedValue; 
     } 
    }; 

    Foo foo = new Foo(Integer.class); 
    assertEquals(expectedValue, foo.doSomething()); 
} 

我相信,在嘲笑核心Java類的限制的原因是由於可能產生不利影響的是嘲諷這樣的類會對因爲核心執行的Java類通常會影響很大一部分代碼。這SO answer遵循類似的路線或推理。

或者它可能與如何在類加載器中加載類有關。我確實讀了a blog post,聲稱通過使用這些命令行參數啓動測試jvm來嘲諷核心類:-Xbootclasspath/a:jmockit.jar: -javaagent:jmockit.jar

+0

我瞭解限制和原因。我想我只是要求一種方法來構造器注入*沒有嘲笑*。具有諷刺意味的是,田野注射將更容易(與'Deencapsulation')... – dcsohl

+0

我會爭辯說,我的上面的例子完成構造函數注入沒有嘲笑。所有的'@ Tested'和'@Injectable'註解都是通過一個構造函數來實例化Foo,該構造函數匹配注入變量並使用指定的值。然而,根據[jmockit api](http://jmockit.org/api1x/mockit/Injectable.html),注射變量實際上是模擬的實例:「這樣的實例可以說是合適的模擬對象,與嘲笑形成對比常規@Mocked類型的實例。「我上面例子中唯一的嘲諷是Bar類。 – TheEllis

+0

另外,如果你不想要的話,你甚至不必嘲笑Bar類,雖然這會使得測試成爲一個集成測試而不是單元測試。 – TheEllis