在控制器测试中使用 Mockito 'when'

Using Mockito 'when' in controller testing

我正在尝试在 Play 框架 2.4.6 中测试我的控制器方法。 在我的控制器方法中,我有以下代码:

User user = accountService.getUserByEmail(email);
if (user == null) {
  //Path A
}
//Path B

当运行测试时,user将为空。因此我无法测试 Path B。我尝试使用 Mockito when 返回一个用户,但它也没有用。还有其他方法吗?

下面是我的测试代码:

    RequestBuilder request = new RequestBuilder()
            .method("POST")
            .bodyForm(ImmutableMap.of("email", "test@test.com"))
            .uri(controllers.routes.ResetPasswordController.postResetPassword().url());

    when(accountService.getUserByEmail(anyString())).thenReturn(new User());

    assertEquals(OK, route(request).status());

感谢@Andriy 为我指明了依赖注入的正确方向。
我设法通过以下设置解决了这个问题。

测试:

public class TestClass {
@Inject
Application application;

final AccountService accountServiceMock = mock(AccountService.class);

@Before
public void setup() {
    Module testModule = new AbstractModule() {
        @Override
        public void configure() {
            bind(AccountService.class).toInstance(accountServiceMock);
        }
    };

    GuiceApplicationBuilder builder = new GuiceApplicationLoader()
            .builder(new ApplicationLoader.Context(Environment.simple()))
            .overrides(testModule);
    Guice.createInjector(builder.applicationModule()).injectMembers(this);

    Helpers.start(application);
}

@Test
public void testMethod() throws Exception {
    RequestBuilder request = new RequestBuilder()
            .session("userId", "1")
            .uri(controllers.routes.AccountController.addAccount().url());

    running(application, () -> {
        when(accountServiceMock.addAccount().thenReturn(true);
        assertEquals(OK, route(request).status());
    });
}

控制器:

@Singleton
public class AccountController extends Controller {
  private AccountService accountService;

  @Inject
  public Controller(AccountService a) {
      accountService = a;
  }

  public Result addAccount() {
     boolean success = accountService.addAccount();
  }
}

接口:

@ImplementedBy(AccountServiceImpl.class)
public interface AccountService {
   boolean addAccount();
}

实施:

public class AccountServiceImpl implements AccountService {
   @Override
   public boolean addAccount() {
   }
}

我对这里的概念知之甚少,但大致是:

  • Controller 就像 HTML 一样是无状态的,因此您需要运行时依赖注入来让 Play 识别模拟对象。

有用的文档: https://www.playframework.com/documentation/2.4.x/JavaTestingWithGuice https://www.playframework.com/documentation/2.4.x/JavaDependencyInjection