【问题标题】:How to Write TestCase in Java for this Service?如何用 Java 为这个服务编写 TestCase?
【发布时间】:2015-01-17 20:42:53
【问题描述】:

我有这门课

public class AuthenticationModule {

    String userName = "foo";
    String password = "bar";

    public void setUserName(String userName) {
         this.userName = userName;
    }

    public void setPassword(String password ) {
         this.password = password ;
    }

    AuthenticationServicePort authenticationServicePort;
    AuthenticationService port;

    private boolean authenicate(String userName, String password) {

        authenticationServicePort = new AuthenticationServicePort();
        port = authenticationServicePort.getAuthenticationServiceProxy();
        return port.login(userName, password);
    }

    public boolean validateUser() {

        return authenicate(userName, password);
    }
}

AuthenticationServicePort 返回一个 WSDL 端口 我想用 Mock AuthenticationServicePort 创建一个简单的测试用例,它将返回一个“真/假”值

如何在不更改 java 代码的情况下注入我自己的 MockObject? 或者更糟糕的情况,什么是最简单的改变方法,使其更容易测试。

【问题讨论】:

  • 请使用 Easymock-powermock 并先尝试一下,如果遇到问题,这里的人可以随时提供帮助
  • AuthenticationServicePort 是您自己的课程,还是您无法更改的库中的内容?如果是后者,它是在接口中实现还是扩展抽象类,以便您可以创建另一个具有相同方法的类来实现/扩展相同的接口/抽象类?
  • 它来自一个库,它不扩展或实现类/接口。 AuthenicationService 是一个我希望模拟的接口,但我的问题似乎是硬编码的 'authenticationServicePort = new AuthenticationServicePort();'
  • 那么您可能需要创建一个实现接口的“包装器”类。包装类将包含一个 AuthenticationServicePort 作为私有字段,并且该类的方法可以基本上只是调用AuthenticationServicePort 上的相同方法(没有理由接口必须完全不过一样)。实现相同接口的另一个类将实现与模拟相同的方法。然后,您将声明 authenticationServicePort 为您的新接口,并注入该接口的一个实例。

标签: java unit-testing junit mocking jmockit


【解决方案1】:

这是一个使用 JMockit 1.13 模拟 AuthenticationServicePort 的示例测试:

public class AuthenticationModuleTest
{
    @Tested AuthenticationModule authentication;
    @Mocked AuthenticationServicePort authenticationService;
    @Mocked AuthenticationService port;

    @Test
    public void validateUser()
    {
        final String userName = "tester";
        final String password = "12345";
        authentication.setUserName(userName);
        authentication.setPassword(password);
        new Expectations() {{ port.login(userName, password); result = true; }};

        boolean validated = authentication.validateUser();

        assertTrue(validated);
    }
}

【讨论】:

    【解决方案2】:

    您应该避免创建内部具有任何逻辑的类的实例(不是普通的 DTO 对象)。相反,您应该以依赖注入容器可以构建完整的对象图的方式设计您的类。在您的代码中,您需要回答自己是否每次调用 authenicate 方法都需要一个新的 AuthenticationServicePort 实例?如果是,那么您应该使用factory 模式来创建该对象的实例,并且应该注入该工厂(在构造函数中提供),以便您可以模拟它以及它将产生的所有内容。如果authenticate 方法的许多调用可以重用AuthenticationServicePort 的相同实例,那么只需注入它(在构造函数中提供)并在您的测试中提供模拟而不是实际实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-14
      • 1970-01-01
      相关资源
      最近更新 更多