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()如果我要以传统方式测试我的控制器,该方法似乎没用。

当然,我可以按照 Play 推荐的方式测试控制器,但是我的应用程序依赖于外部 SOAP Web 服务,因此我需要进行单元测试来证明我们的代码在服务器关闭时可以正常工作。

那么,使用 mock 对 Play 控制器进行单元测试,同时仍然利用setup()andteardown()方法的最佳方法是什么?

编辑

我意识到我在这里假设了一些知识,所以对于那些不知道的人来说,单元测试中的控制器实例必须包含在一个running()函数或 Play 中!将抛出运行时异常,说明尚未启动任何应用程序。

4

1 回答 1

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);
  }
于 2012-09-19T14:02:38.917 回答