簡體   English   中英

如何對使用 Java UUID 的代碼進行單元測試?

[英]How do I unit test code which uses Java UUID?

我有一段代碼,預計會用 Java UUID ( UUID.randomUUID() ) 填充響應對象的一個​​屬性。

如何從外部對該代碼進行單元測試以檢查此行為? 我不知道將在其中生成的 UUID。

需要測試的示例代碼:

// To test whether x attribute was set using an UUID
// instead of hardcode value in the response
class A {
  String x;
  String y;
}

// Method to test
public A doSomething() {
  // Does something
  A a = new A();
  a.setX( UUID.randomUUID());
  return a;
}

Powermock 和靜態模擬是前進的方向。 你將需要類似的東西:

    ...
    import static org.junit.Assert.assertEquals;
    import static org.powermock.api.mockito.PowerMockito.mockStatic;
    ...

    @PrepareForTest({ UUID.class })
    @RunWith(PowerMockRunner.class)
    public class ATest
    {
    ...
      //at some point in your test case you need to create a static mock
      mockStatic(UUID.class);
      when(UUID.randomUUID()).thenReturn("your-UUID");
    ...
    }

請注意,靜態模擬可以在用 @Before 注釋的方法中實現,因此它可以在所有需要 UUID 的測試用例中重復使用,以避免代碼重復。

一旦靜態模擬被初始化,UUID 的值可以在您的測試方法中的某處斷言,如下所示:

A a = doSomething();
assertEquals("your-UUID", a.getX());

當您需要模擬時,類/靜態方法變得非常痛苦。 我最終所做的將使您免於使用模擬系統的是使用帶有實現靜態方法的接口的瘦包裝器類。

在您的代碼中,實例化/注入並使用包裝類而不是靜態方法。 這樣你就可以用模擬替換它。

編輯:在單元測試方面獲得了更多經驗,我會選擇 ThinkBonobo 的答案。 創建一個接口、一個假實現和一個具體實現,如下所示:

public interface UuidProvider {
    UUID uuid();

    class Fake implements UuidProvider {
        @Override
        public UUID uuid() {
            return UUID.fromString("0000-00-00-00-000000");
        }
    }
}

public class RandomUuidProvider implements UuidProvider {
    @Override
    public UUID uuid() {
        return UUID.randomUUID();
    }
}

注入UuidProvider.Fake在您的測試,並RandomUuidProvider在你的產品代碼。

或者在 Kotlin 中:

interface UuidProvider {
    fun uuid(): UUID

    class Fake : UuidProvider {
        override fun uuid() = UUID.fromString("0000-00-00-00-000000")
    }
}

class RandomUuidProvider : UuidProvider {
    override fun uuid() = UUID.randomUUID()
}

我的舊答案如下。


除了 ThinkBonobo 的響應之外,另一種創建 getter 方法(可選地用@VisibleForTesting注釋)的方法,例如String getUUID()可以在您在測試中定義的子類中覆蓋。

關於這個現有問題,似乎我能夠成功模擬出 UUID 的唯一方法是添加我想在@PrepareForTesting下測試的類:

@PrepareForTesting({UUIDProcessor.class})
@RunWith(PowerMockitoRunner.class)
public class UUIDProcessorTest {
    // tests
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM