首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >参数不同!招聘:

参数不同!招聘:
EN

Stack Overflow用户
提问于 2019-10-21 13:09:04
回答 1查看 437关注 0票数 0

我正在为我的以下代码编写单元测试

代码语言:javascript
复制
public class Class1 {
   protected void execute(String a, String b) {
   try{
      process(a,b);
   }
   catch(Exception E){
       Class2.write(e,Class1.class.getSimpleName())
    }
  }

  private void process(String a, String b) {
     validate(a,b);
     // Doing some processing on a and b values
  }

 private void validate (String a, String b) {
    if(a==null || a.isEmpty() || b==null || b.isEmpty())
       throw new IllegalArgumentException("Input value cannot be null or empty");
 }

}

对于上面的代码,我尝试编写一个UT,它涵盖了异常用例。下面是我的UT代码,

代码语言:javascript
复制
@Test

public void test1(){
 try {

            PowerMockito.mockStatic(Class2.class);
            PowerMockito.when(Class2.class, "write", Mockito.anyObject(), Mockito.anyString())
                    .thenCallRealMethod();
            Class1 class1 = new Class1();
            Class2.write(new IllegalArgumentException("Input value cannot be null or empty"),Class1.class.getSimpleClassName());
            PowerMockito.verifyStatic(Class2.class, VerificationModeFactory.times(1));
            class1.execute(Mockito.anyString(),Mockito.anyString());  
        } catch (Exception e) {
            e.printStackTrace();
            Assert.fail(e.getMessage());
        }
}

当我执行上面的测试时,我得到了下面的异常

代码语言:javascript
复制
Argument(s) are different! Wanted:
Class2.write{
java.lang.IllegalArgumentException:Input value cannot be null or empty,
Class1
}

Actual invocation has different arguments:
Class2.write{
java.lang.IllegalArgumentException:Input value cannot be null or empty,
Class1
}

有人能帮我解决这个问题吗?我非常感谢你的帮助和时间

提前感谢

EN

回答 1

Stack Overflow用户

发布于 2019-10-21 13:51:05

你的问题:

IllegalArgumentException不使用字符串message来表示相等。测试字符串消息或类类型会更安全。我更喜欢测试检测类型而不是消息,因为字符串消息不应该用于控制流,它是一个实现细节。

代码语言:javascript
复制
System.out.println(Objects.equals(
    new IllegalArgumentException(), 
    new IllegalArgumentException()));
// false

System.out.println(Objects.equals(
    new IllegalArgumentException().getClass(),
    new IllegalArgumentException().getClass()));
// true

因此,为了模拟这一点,我将使用匹配器:

代码语言:javascript
复制
any(IllegalArgumentException.class), eq(Class1.class.getSimpleName())

关于您的设计的问题:

我将以反对这段代码的结构的论点作为结束,因为它不是围绕依赖注入构建的。您可以调用实例方法,而不是调用静态方法Class2::write

例如,创建接口:

代码语言:javascript
复制
public interface Writer {
    void write(Exception e, String source);
}

现在可以重构该类以提供两个ctor,一个接受任何编写器,另一个缺省为Class2

代码语言:javascript
复制
public class Class1 {
    private final Writer writer;

    public Class1() {
        this(Class2::write);
    }

    public Class1(Writer writer) {
        this.writer = writer;
    }

    protected void execute(String a, String b) {
        try {
            process(a,b);
        }
        catch (Exception E) {
            writer.write(e, Class1.class.getSimpleName());
        }
    }
    ...
}

使用此策略,您现在可以简单地创建Writer的实例模拟。这就避免了使用静态方法来更改应用程序的字节码,并且使您的类更加灵活,因为它现在可以支持许多不同的编写器实现。任何修改应用程序字节码的操作都应该非常谨慎地使用,例如替换静态方法调用,这并不能真正验证代码的运行时执行。

在我看来,大多数PowerMockito/PowerMock只帮助验证那些在构建时没有考虑可测试性/灵活性的代码。对于结构良好的代码,您不需要使用Mockito/EasyMock工具集之外的任何东西。有一些例外,但工具集应该非常谨慎地使用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58480098

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档