2015-05-04 131 views
0

我想測試的服務A,其具有方法methodA1,A指的是一個服務B,其具有方法methodB1,與差豆服務彈簧測試

在methodB1被稱爲在methodA1,

@Service 
class A{ 
    @Autowired 
    B b; 
    void methodA1{ 
     .... 
     b.methodB1(); 
     ..... 
    } 
} 

@Service 
class B{ 

    void methodB1{ 
     .... 
    } 
} 

現在,我想測試methodA1,但方法B1需要重寫,所以我創建了一個新的類BMock;

@Service("bMock") 
class BMock execute B{ 
    @Override 
    void methodB1{ 
    .... 
    } 
} 

測試情況是這樣的:

class testClass extends springTest{ 

    @Autowired 
    A a; 

    @Autowired 
    @Qualifier("bMock") 
    B b; 

    @Test 
    public void testMethodA1(){ 
     a.methodA1(); 
    } 
} 

實際上,在methodA1隨時調用methodB1在B類,我想它來調用BMock測試的情況下,該怎麼辦呢?

+0

爲什麼不使用easymock/powermock/mockito等模擬框架? – SMA

+0

'@Qualifier(「bMock」)'在這種情況下不會做任何事情(AFAIK)。你的界面。而不是concreate'B使用'AnInterfaceThatBImplements b' – Shahzeb

+0

@Shahzeb,你的意思是我需要創建一個接口Ib,B類和BMock實現接口Ib?如果這樣,bMock可以在測試用例中調用嗎? – Mike

回答

0

Spring Re-Inject可用於在測試環境中用mocks代替bean。

@ContextConfiguration(classes = {ReInjectContext.class, testClass.TextContext.class}) 
class testClass extends springTest { 
    @Autowired 
    A a; 

    // Spring context has a bean definition for B, but it is  
    // overridden in the test's constructor, so BMock is created 
    // instead of B. BMock gets injected everywhere, including A and the 
    // test 
    @Autowired 
    B b; 
    public testClass() { 
      // Replace bean with id "b" with another class in constructor 
      // "b" is bean ID that Spring assigns to B 
      ReInjectPostProcessor.inject("b", BMock.class); 
    } 

    @Test 
    public void testMethodA1(){ 
     a.methodA1(); 
    } 

    // If A and B are already the part of Spring context, this config 
    // is not needed 
    @Configuration 
    static class TestContext { 
     @Bean public A a() { return new A(); } 
     @Bean public B b() { return new B(); } 
    } 
} 

而且從BMock

0

刪除@Qualifier和@Service如果你有一個設置爲A類b,明確地將其覆蓋在測試:

class testClass extends springTest{ 

    @Autowired 
    A a; 

    @Autowired 
    @Qualifier("bMock") 
    B b; 

    @Test 
    public void testMethodA1(){ 
     a.setB(b); 
     a.methodA1(); 
    } 
} 

如果您有沒有setter(並且不想創建它),您可以使用反射:

Field bField = A.getDeclaredField("b"); 
fField.setAccessible(true); 
fField.set(a, b); 

它打破私人領域的興起,但對於測試可能是可以接受的。