2012-06-20 64 views
8

標題幾乎說明了一切。我想設置一個傳統的JUnit測試來模擬控制器的依賴關係,並針對動作運行測試。單元測試使用模擬播放控制器

我發現,我能實現我的目標是這樣的:

public class AccountsControllerTest { 
    private controllers.Accounts accountsController; 

    @Test 
    public void test() { 
     running(fakeApplication(), new Runnable() { 
      public void run() { 
       accountsController = new controllers.Accounts(); 
       accountsController.setAccountsWorkflow(mock(workflow.Accounts.class)); 
      } 
     }); 
    } 
} 

這裏明顯的問題是,我實例測試我的類和測試方法本身,注射模擬的依賴,當我應該在setup()方法中這樣做。看來setup()方法是無用的,如果我要以傳統方式測試我的控制器。

當然,我可以測試控制器the way Play recommends,但我的應用程序依賴於外部SOAP Web服務,所以我需要進行單元測試以顯示我們的代碼在服務器關閉時運行。

那麼,什麼是使用mock單元測試Play控制器的最佳方法,同時仍然利用setup()teardown()方法的優勢?

編輯

我知道我在這裏假設一些知識,所以對於那些誰不知道,在單元測試控制器實例必須被包裹在一個running()功能或播放!會拋出一個運行時異常,說沒有應用程序已經啓動。

+0

http://www.joergviola.de/blog/2012/06/04/page-driven-functional-tests-for-play-2-dot-0/是一個很好的測試方法,但仍然存在模擬問題。你可以嘗試運行沒有fakeApplication的測試。請參閱http://stackoverflow.com/questions/10381354/how-to-manipulate-session-request-and-response-for-test-in-play2-0 – niels

+0

http://stackoverflow.com/a/10114621/89509 –

+0

謝謝你的例子。你如何能夠在'running'函數外實例化控制器?這個約束是阻止我利用JUnit的'setup'方法,所以我不必在每個測試方法上設置mock。你的例子並沒有真正證明這一點。 – Samo

回答

1

您可以使用Mockito和Play的FakeApplication並設置靜態Http.Context變量來完成此操作。

這樣就可以像所有其他JUnit測試一樣編寫測試。

實施例:

... 
import static play.test.Helpers.status; 
import play.test.FakeApplication; 
import play.test.Helpers; 
import play.mvc.Http; 
import play.mvc.Result; 
... 

@RunWith(MockitoJUnitRunner.class) 
public class ApplicationTest { 

    public static FakeApplication app; 

    @Mock 
    private Http.Request request; 

    @BeforeClass 
    public static void startApp() { 
     app = Helpers.fakeApplication(); 
     Helpers.start(app); 

    } 

    @Before 
    public void setUp() throws Exception { 
     Map<String, String> flashData = Collections.emptyMap(); 
     Http.Context context = new Http.Context(request, flashData, flashData); 
     Http.Context.current.set(context); 
    } 

    @Test 
    public void testIndex() { 
     final Result result = Application.index(); 
     assertEquals(play.mvc.Http.Status.OK, status(result)); 
    } 

    @AfterClass 
    public static void stopApp() { 
     Helpers.stop(app); 
    } 
+0

我不知道你可以設置當前的Http.Context - 這很酷;謝謝。 – duma

+0

我發現通過設置'Http.Context.current.set(context);'我的後續測試依賴於應用程序失敗。所以你必須在@AfterClass中將上下文設置回原來的狀態。 –