gpt4 book ai didi

java - 论据不同!通缉:

转载 作者:行者123 更新时间:2023-12-01 22:43:41 25 4
gpt4 key购买 nike

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

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代码,

@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());
}
}

当我执行上述测试时,出现以下异常

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
}

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

提前致谢

最佳答案

您的问题:

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

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

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

所以为了模拟这个我会使用匹配器:

any(IllegalArgumentException.class), eq(Class1.class.getSimpleName())
<小时/>

您的设计存在问题:

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

例如创建接口(interface):

public interface Writer {
void write(Exception e, String source);
}

您现在可以重构该类以提供两个构造函数,一个接受任何编写器,另一个默认为 Class2

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 仅有助于验证未考虑到可测试性/灵 active 而构建的代码。您不需要使用 Mockito/EasyMock 工具集之外的任何内容来获得结构良好的代码。有一些异常(exception),但应该非常谨慎地使用工具集。

关于java - 论据不同!通缉:,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58480098/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com