Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 延迟EasyMock验证_Java_Unit Testing_Junit_Mocking_Easymock - Fatal编程技术网

Java 延迟EasyMock验证

Java 延迟EasyMock验证,java,unit-testing,junit,mocking,easymock,Java,Unit Testing,Junit,Mocking,Easymock,我正在使用EasyMock为Java中的JUnit测试创建模拟对象。我创建了一个模拟对象,并将其传递给另一个线程,它希望在那里调用方法。在另一个线程中,调用被封装在一个try/catch(Throwable)块中,因此当模拟上发生意外调用并因此抛出AssertionError时,该错误被catch块捕获并处理。因此,即使发生了意外调用,测试还是通过了 为了让测试如预期的那样失败,我想延迟所有对EasyMock.verify(mock)调用的验证,这些调用在测试运行程序线程结束时进行。这是可能的吗

我正在使用EasyMock为Java中的JUnit测试创建模拟对象。我创建了一个模拟对象,并将其传递给另一个线程,它希望在那里调用方法。在另一个线程中,调用被封装在一个
try/catch(Throwable)
块中,因此当模拟上发生意外调用并因此抛出
AssertionError
时,该错误被catch块捕获并处理。因此,即使发生了意外调用,测试还是通过了


为了让测试如预期的那样失败,我想延迟所有对
EasyMock.verify(mock)
调用的验证,这些调用在测试运行程序线程结束时进行。这是可能的吗?怎么可能?

我想正确的解决方案是停止捕捉可丢弃的
。这样做会捕获您正在查找的所有
错误,这可能非常危险。。。您是否绝对100%确定您需要捕获可丢弃的
?为什么?


(如果您确实这样做了,您可以捕获断言错误并重新显示它。但这很难看!)

我不确定如何使用EasyMock执行此操作,但这种行为在中是可能的,因为可以在测试结束时指定验证断言。

尝试使用漂亮的模拟:

“好笑 在createMock()返回的模拟对象上,所有方法的默认行为都是为所有意外的方法调用抛出AssertionError。如果您想要一个默认允许所有方法调用并返回适当空值(0、null或false)的“好”模拟对象,请改为使用createMock()


对于意外调用,将返回默认值,而不是抛出AssertionError,但是您仍然可以使用verify()方法验证它们(在这种情况下,将抛出AssertionErrors)

正如@deterb建议的那样,可以使用Mockito,但您必须知道方法名称,或者必须为每个方法设置期望值。以下是一个例子:

模拟接口:

public interface MyInterface {

    void allowedMethod();

    void disallowedMethod();
}
捕获断言错误的用户类

public class UserClass {

    public UserClass() {
    }

    public static void throwableCatcher(final MyInterface myInterface) {
        try {
            myInterface.allowedMethod();
            myInterface.disallowedMethod();
        } catch (final Throwable t) {
            System.out.println("Catched throwable: " + t.getMessage());
        }
    }
}
以及Mockito测试:

@Test
public void testMockito() throws Exception {
    final MyInterface myInterface = mock(MyInterface.class);

    UserClass.throwableCatcher(myInterface);

    verify(myInterface, never()).disallowedMethod(); // fails here
}
EasyMock也可以做到这一点,但需要做一些工作:

@Test
public void testEasyMock() throws Exception {
    final AtomicBoolean called = new AtomicBoolean();
    final MyInterface myInterface = createMock(MyInterface.class);
    myInterface.allowedMethod();

    myInterface.disallowedMethod();
    final IAnswer<? extends Object> answer = new IAnswer<Object>() {

        @Override
        public Object answer() throws Throwable {
            System.out.println("answer");
            called.set(true);
            throw new AssertionError("should not call");
        }

    };
    expectLastCall().andAnswer(answer).anyTimes();

    replay(myInterface);

    UserClass.throwableCatcher(myInterface);

    verify(myInterface);
    assertFalse("called", called.get()); // fails here
}
以及对它的测试:

@Test
public void testEasyMockWithCustomClass() throws Exception {
    final MyInterface myInterface = createMock(MyInterface.class);
    myInterface.allowedMethod();

    final MockedMyInterface mockedMyInterface = 
        new MockedMyInterface(myInterface);

    replay(myInterface);

    UserClass.throwableCatcher(mockedMyInterface);

    verify(myInterface);
    assertFalse("called", mockedMyInterface.isCalled()); // fails here
}

我们捕获了Throwable(丑陋,我同意),因此我们可以拦截(例如)内存不足错误,并进行一些日志记录,然后从此点干净地重新启动应用程序。如果没有其他解决方案,我可能会求助于捕获AssertionError。@Steven-捕获AssertionError并重新引用它几乎肯定比无条件的
catch(Throwable t)
block.:-)我也同意deterb的建议:Mockito确实提供了一个更简单的模拟机制(即不必担心nice/strick模拟),并且您只能验证您实际需要的行为。+1:当您当前的库提供您需要的功能时,切换库是不值得的-1:一个好的mock会接受任何方法调用,因此不允许测试是否发生了意外调用(只有在预期调用没有发生的情况下);不过,我试着用它做实验,却找不到更好的解决办法。也许您可以尝试降低测试的粒度,例如测试更具体的方法。
@Test
public void testEasyMockWithCustomClass() throws Exception {
    final MyInterface myInterface = createMock(MyInterface.class);
    myInterface.allowedMethod();

    final MockedMyInterface mockedMyInterface = 
        new MockedMyInterface(myInterface);

    replay(myInterface);

    UserClass.throwableCatcher(mockedMyInterface);

    verify(myInterface);
    assertFalse("called", mockedMyInterface.isCalled()); // fails here
}