44

私のコード:

@Component
public class A {
    @Autowired
    private B b;

    public void method() {}
}

public interface X {...}

@Component
public class B implements X {
    ...
}

分離クラスAでテストしたいのですが、クラスBをモックする必要がありますか?はいの場合、どのように?自動配線されており、モックオブジェクトを送信できるセッターがないためです。

4

4 に答える 4

83

分離クラス A でテストしたい。

B のインスタンスをインスタンス化して注入するのではなく、B を完全にモックする必要があります。ポイントは、B が機能するかどうか A をテストすることです。そのため、壊れている可能性のある B が A のテストに干渉することを許可しないでください。

そうは言っても、私はMockitoを強くお勧めします。モッキング フレームワークのように、非常に使いやすいです。次のように記述します。

@Test
public void testA() {
    A a = new A();
    B b = Mockito.mock(B.class); // create a mock of B
    Mockito.when(b.getMeaningOfLife()).thenReturn(42); // define mocked behavior of b
    ReflectionTestUtils.setField(a, "b", b); // inject b into the B attribute of A

    a.method();

    // call whatever asserts you need here
}
于 2010-09-08T05:01:26.547 に答える
18

これは、Spring 3.1、JUnit 4.7、およびMockito1.9でテストを機能させる方法の例です。

FooService.java

public class FooService {
    @Autowired private FooDAO fooDAO;
    public Foo find(Long id) {
        return fooDAO.findById(id);
    }
}

FooDAO.java

public class FooDAO {
    public Foo findById(Long id) {
        /* implementation */
    }
}

FooServiceTest.java

@RunWith(MockitoJUnitRunner.class)
public class FooServiceTest {
    @Mock private FooDAO mockFooDAO;
    @InjectMocks private FooService fooService = new FooService();

    @Test public final void findAll() {
        Foo foo = new Foo(1L);
        when(mockFooDAO.findById(foo.getId()).thenReturn(foo);

        Foo found = fooService.findById(foo.getId());
        assertEquals(foo, found);
    }
}
于 2012-07-23T01:40:31.590 に答える
15

ReflectionTestUtils.setFieldSpring (または junit 拡張機能)を使用してリフレクションを介してフィールドを注入するかPrivateAccessor、モック アプリケーション コンテキストを作成してそれをロードすることができます。単純なユニット (非統合) テストの場合は、単純にするためにリフレクションを使用することをお勧めします。

于 2010-09-07T17:26:18.357 に答える
0

このフォーラムでの議論は私にとって理にかなっています。プライベート メンバー b を、クラス B (つまり、サービス指向) によって実装される InterfaceB の型として宣言し、MockB クラスも同じインターフェイスを実装することを宣言できます。テスト環境のアプリケーション コンテキストで MockB クラスを宣言し、本番アプリケーション コンテキストで通常の B クラスを宣言します。いずれの場合も、クラス A のコードは自動配線されるため、変更する必要はありません。

于 2010-09-07T17:34:53.187 に答える