16

Java 6、JUnit 4.8.1 を使用して、コンソール アプリケーションを作成しています。私のアプリケーションには、公開されていないメンバー フィールドがあります…</p>

public class MyApp { 
    ...
    private OpportunitiesService m_oppsSvc;

    private void initServices() { 
        …
        m_oppsSvc = new OpportunitiesServiceImpl(…);
    }
    ...
}

m_oppsSvc.getResults()サービスから 1 つのメソッドが呼び出されるたびに (例: )、常に同じ結果が返されるように、動作をモックしたいと考えています。それ、どうやったら出来るの?フィールドの設定メソッドはありません。現在、Mockito 1.8.4 を使用しています。Mockito または他のモック フレームワークでこれを行うことは可能ですか?

4

6 に答える 6

13

これはあなたが望むものです:

@RunWith(MockitoJUnitRunner.class)
public class MyAppTest { 

    @Mock private OpportunitiesService mocked_m_oppsSvc;
    @InjectMocks MyApp myApp;

    @Test public void when_MyApp_uses_OpportunititesService_then_verify_something() { 
        // given
        given( mocked_m_oppsSvc.whatever()).willReturn(...);

        // when
        myApp.isUsingTheOpportunitiesService(...);

        // then
        verify...
        assertThat...
    }
}

使用: Mockito 1.9.0BDD スタイルFEST-Assert AssertJ

それが役立つことを願っています:)

于 2012-07-20T22:55:22.127 に答える
10

すでにmockitoを使用していることを考えると、リフレクションを使用しないのはなぜですか:

@RunWith(MockitoJUnitRunner.class)
public class MyApp { 

    @Mock
    private OpportunitiesService m_oppsSvc;

    private MyApp myApp;


    @Before
    public void before() throws Exception {
       myApp = new MyApp();
       Field f = MyApp.class.getDeclaredField("m_oppsSvc");
       f.setAccessible(true);
       f.set(myApp, m_oppsSvc);
    }
}

少し醜いですが、うまくいきます。これは Mockito で最も効率的な方法ではないかもしれませんが、うまくいくことに注意してください。

また、Whitebox クラスを使用してこれを行うことができる Powermock もあります。Powermock の詳細については説明しませんが、プライベート フィールド値を注入する呼び出しは次のとおりです。これはモック オブジェクトである必要があります。

Whitebox.setInternalState(myApp, "m_oppsSvc", m_oppsSvc);
于 2012-07-21T01:17:41.667 に答える
6

private フィールドをにおいとしてモックする試みを考慮する必要があります。つまり、実行しようとしていることが正しくないか、コードが現在正しく構造化されていないことを示しています。public メソッドまたは注入された依存関係をモックするだけでよい

指定したコードでは、次のように OpportunitiesService を挿入することを検討する必要があります。

public class MyApp { 
    ...
    private OpportunitiesService m_oppsSvc;

    public MyApp(OpportunitiesService oppsSvc) {
        this.m_oppsSvc = oppsSvc;
    }
    ...
}

テストでは、次のようにモックを挿入できます。

OpportunitiesService mockOpportunitiesService =
    Mockito.mock(OpportunitiesService.class);
Mockit.when(mockOpportunitiesService.someMethod()).thenReturn(someValue);
MyApp app = new MyApp(mockOpportunitiesService);
于 2012-07-20T20:41:18.703 に答える
0

JMockit で簡単に実行できます。

public class MyAppTest
{
    @Tested MyApp myApp;

    @Test
    public testSomething(final @Capturing OpportunitiesService mockService)
    {
        new NonStrictExpectations() {{
            mockService.getResults(); result = asList("a", "b", "C");
            // record other expectations, if needed
        }};

        myApp.whateverMethodIWantToTest();

        new Verifications() {{
            mockService.doSomething(anyInt);
            // verify other expectations, if needed
        }};
    }
}

実装クラスOpportunitiesServiceImplはテスト コードで言及されていませんが、そのインスタンス (任意の数) は引き続き適切にモックされます。

于 2012-07-20T20:52:12.657 に答える
-1

一般に、依存性注入を使用し、モック オブジェクト (タイプ OppportunitiesServiceImpl) をコンストラクター、別のセッターを介して、またはメソッド (getResults) に直接渡す必要があります。最初に OpportunitiesServiceImpl のインターフェースを抽出する必要がある場合があります。

于 2012-07-20T20:39:04.920 に答える
-1

通常、これは依存性注入を使用して解決されます。通常の (本番) モードでは、依存性注入コンテナー (Spring や Guice など) は、コンストラクターまたはセッターを介してのインスタンスをOpportunitiesService注入します。MyApp

次に、テスト中に、同じセッターまたはコンストラクター引数を使用して手動でモック インスタンスを「注入」できます。

する代わりに

m_oppsSvc = new OpportunitiesServiceImpl(…);

のコンストラクタOpportunitesServiceを介して渡してみてくださいMyApp

于 2012-07-20T20:39:45.490 に答える