[英]incorrect findbugs “Nonnull field is not initialized” error in junit
import org.junit.Test;
import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
import edu.umd.cs.findbugs.annotations.NonNull;
@DefaultAnnotation(NonNull.class)
public class FooTest {
private Foo foo;
@Before
public void setUp() throws ParseException {
foo = ...;
}
@Test
public void testScenario1() {
foo.getId();
...
}
}
這會導致findbug失敗,原因是:
NP: Nonnull field foo is not initialized
by new FooTest( (NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR)
這是為什么? FindBugs是否看不到這是一個junit測試? (因此,在執行每個測試之前調用setUp())
一種解決方法是添加此類注釋:
@SuppressWarnings(
value="NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR",
justification="it is initialized in setUp()")
但這不是很好。 有更好的主意嗎?
這是為什么? FindBugs是否看不到這是一個junit測試? (因此,在執行每個測試之前調用setUp())
基本上是。 很明顯,FindBugs對JUnit測試用例及其工作方式沒有特殊的了解。 (我對您甚至在單元測試中運行FindBugs感到有些驚訝...)
一種解決方法是添加此類注釋...有更好的主意嗎?
將字段顯式初始化為null
更簡單。 那將使FindBugs滿意。
是的,我猶豫要在測試中添加NonNull注釋; 但是測試本身可能包含錯誤,那為什么不呢? 為什么不通過單元測試運行FindBugs?
因為這樣的問題!
單元測試在質量上與普通代碼不同。 例如,如果foo
字段意外地留為null
,那么可能發生的最壞情況是單元測試將崩潰,您將發現並修復該錯誤。 它不會直接破壞生產代碼,並且僅在您習慣忽略失敗的單元測試的情況下才有任何影響。
我無法將foo初始化為null,因為它被定義為NonNull(通過DefaultAnnotation)
根據TimK的回答,這意味着在構造函數執行完之后foo
必須為非null。 假定您已為整個代碼庫(包括測試用例)指定了不變式,則必須堅持不變或添加異常。
一個麻煩可能是創建一個虛擬Foo
實例,並使用該實例來初始化foo
。 但是,僅添加SuppressWarnings更為直接...
坦白說,您需要對FindBugs想要實現的目標進行更深入的思考。 在單元測試中運行它似乎會產生比其解決的問題更多的問題。
注釋“ @DefaultAnnotation(NonNull.class)”表示將foo視為由@NonNull進行注釋。 這意味着foo在其生命周期內不允許為null 。 在您的測試中,在實例化類與調用setUp之間的時間為null。 因此,FindBugs可正確報告此問題。
您是否可以粘貼一個真實的代碼段,以發出相同的警告,而不是您給出的示例?
原因是昨天我碰到了這種確切的findbugs情況,但這是因為輸入錯誤:
public class FooTest {
private Foo foo;
@Before
public void setUp() throws ParseException {
Foo foo = ...;
}
您會注意到我有Foo foo
。 這定義了foo的本地方法實例並對其進行初始化,而不是初始化private class屬性。
我知道您在上面的代碼段中沒有這樣做,但是我想知道您項目中的實際代碼是否正在犯此錯誤。 它是一個簡單的錯字檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.