2011-04-06 50 views
0

我在嘗試在我的測試用例中的有線bean中設置模擬對象時出現問題。如何在基於代理的Spring bean中設置模擬對象?

這裏是我的簡單的問題: -

class SomeClassTest { 
    @Autowired 
    private SomeClass someClass; 

    @Test 
    public void testRun() { 
     Service service = mock(ServiceImpl.class); 
     when(service.doIt()).thenReturn(""); 

     // this line fails with ClassCastException 
     ((SomeClassImpl) someClass).setService(service); 

     assertEquals("bad", someClass.run()); 
    } 
} 

interface SomeClass { 
    String run(); 
} 

class SomeClassImpl implements SomeClass { 
    private Service service; 

    public void setService(Service service) { 
     this.service = service; 
    } 

    public String run() { 
     String value = service.doIt(); 
     return StringUtils.isBlank(value) ? "bad" : "good"; 
    } 
} 

interface Service { 
    String doIt(); 
} 

class ServiceImpl implements Service { 
    public String doIt() { 
     return "bla"; 
    } 
} 

在這個例子中,我試圖嘲弄了Service.doIt(),這樣我可以測試不同條件下測試SomeClass。我面臨的問題是我不知道我應該如何在SomeClass中設置模擬服務對象。我能想到的唯一方法是將SomeClass降爲具體類以調用setService(...),但是,我收到一個ClassCastException,說$ Proxy與SomeClassImpl不兼容。我相信我所有的bean佈線都是基於代理的,因爲我使用AOP來配置事務。我真的不想在SomeClass接口中暴露setService(...),因爲在我的生產代碼中這樣做沒有意義。

有沒有辦法讓我做到這一點?

謝謝。

+0

測試實現,而不是接口。 – sapientpants 2011-04-06 21:22:01

+0

@pansapien和@ericacm:在這種情況下,我不能使用'new'來實例化它,因爲'SomeClassImpl'包含了其他未被模擬的有線bean。我上面的例子非常簡單。 – limc 2011-04-07 02:52:32

+0

是否有理由不把接受器添加到接口?測試要求是有效的設計要求,特別是如果它們消除了跳過籃圈的需要。 – sapientpants 2011-04-07 14:49:44

回答

1

可以使用@Resource批註get the implementation

@Resource 
private SomeClassImpl someClass; 
... 
someClass.setService(service); 
... 
+0

誰知道這是否仍然是5年後做事情的有效方式,但是當我嘗試這樣做時,我得到的錯誤是沒有[com.example.service.SomeServiceImpl]類型的合格bean。 – aarestad 2016-04-01 17:53:07

0
  1. 使用服務設置器的額外接口。 或
  2. 不要autowire Service但在測試中使用'new'運算符。
相關問題