Junit 使用模拟对播放控制器进行单元测试

Junit 使用模拟对播放控制器进行单元测试,junit,controller,playframework,mocking,playframework-2.0,Junit,Controller,Playframework,Mocking,Playframework 2.0,标题几乎说明了一切。我想设置一个传统的JUnit测试来模拟控制器的依赖关系,并针对操作运行测试 我发现我可以像这样实现我的目标: public class AccountsControllerTest { private controllers.Accounts accountsController; @Test public void test() { running(fakeApplication(), new Runnable() {

标题几乎说明了一切。我想设置一个传统的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()
方法似乎是无用的

当然,我可以测试控制器,但我的应用程序依赖于一个外部soapweb服务,因此我需要进行单元测试,以表明我们的代码在服务器停机时工作正常

那么,在仍然利用
setup()
teardown()方法的情况下,使用mock对播放控制器进行单元测试的最佳方法是什么

编辑


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

您可以使用Mockito和Play的FakeApplication并设置静态Http.Context变量来完成此操作

通过这种方式,您可以像编写所有其他JUnit测试一样编写测试

例如:

。。。
导入静态play.test.Helpers.status;
导入play.test.FakeApplication;
导入play.test.Helpers;
导入play.mvc.Http;
导入play.mvc.Result;
...
@RunWith(MockitoJUnitRunner.class)
公共类应用程序测试{
公共静态伪造应用程序;
@嘲弄
私有Http请求;
@课前
公共静态无效startApp(){
app=Helpers.fakeApplication();
Helpers.start(应用程序);
}
@以前
public void setUp()引发异常{
Map flashData=Collections.emptyMap();
Http.Context Context=新的Http.Context(请求、flashData、flashData);
Http.Context.current.set(Context);
}
@试验
公共无效测试索引(){
最终结果=Application.index();
assertEquals(play.mvc.Http.Status.OK,Status(result));
}
@下课
公共静态void stopap(){
Helpers.stop(应用程序);
}

也是一种很好的测试方法,但仍然存在模拟问题。您可以尝试在不使用伪造应用程序的情况下运行测试。请参阅示例。您是如何在
running
函数之外实例化控制器的?此约束阻止我利用JUnit的
setup
方法,因此我没有在每个测试方法上设置模拟。您的示例并没有真正演示这一点。@Samo is有什么问题吗?我希望能够验证从控制器返回的视图,但不是通过检查HTML内容。我希望验证是否传递了正确的视图名。我不知道此数据是否可用于播放的
结果
类型。似乎不是。您可以使用我问题中显示的格式使用模拟对控制器进行单元测试,但您将无法使用
设置()
method,所以您将在测试方法之间重复大量的模拟。我不知道您可以像这样设置当前的Http.Context——这很酷;谢谢。我通过设置
Http.Context.current.set(Context)发现了这一点;
依赖于应用程序的后续测试失败。因此,您必须在@AfterClass中将上下文设置回其原始状态。
...
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);
  }