繁体   English   中英

Mockito doThrow() 不抛出异常

[英]Mockito doThrow() not throwing exception

有类似的问题,但没有一个可以解决我目前的问题

假设我有一个相当简单的类:

public class ClassA {
    private final Object someVariable;
    
    public classA(Object obj) {
        this.someVariable = obj
    }

    public void Object someMethod(Object obj) throws SomeException {
    //does stuff
    }
}

现在,我在 diff 类中创建此类的一个实例

public class ClassB {
    private final Object anotherVariable;

    public void Object anotherMethod() throws SomeException {
        try {
            ClassA objectA = new ClassA(anotherVariable)
            objectA.someMethod()
        } catch {
            // does stuff
        }
    }
}

最终目标是通过抛出异常来测试 catch 块

@Mock
ClassA myObject = new ClassA(obj)

...

@Test(expected = SomeException.class)
public void myTest()throws Exception {
    doThrow(new SomeException()).when(myObject).someMethod(any());
}

出于某种原因,从未抛出异常。 我也试过用有效和无效的对象替换any() ,但它仍然不起作用。

编辑1:

在寻找解决方案的同时,由于某种原因,这通过了测试:

@Test(expected = SomeException.class)
public voif Test() throws Exception {     
    doThrow(new someException()).when(myObject).someMethod(any());
    when(myObject.someMethod(any())).thenThrow(new someException());
}

关于为什么这有效的任何解释? 这是不好的做法还是什么?

我相信原因是你从不调用该方法:

@Test(expected = SomeException.class)
public void myTest(0 throws Exception {
    // here you stub the method
    doThrow(new SomeException()).when(myObject).someMethod(any());
    // also it should probably be like this:
    // doThrow(new SomeException()).when(myObject).someMethod();
    // because the method in ClassA does not have any params

    // you need it to be called somewhere
    // you can do that explicitly
    myObject.someMethod(/*perhaps some param here*/);

    // or you can call some other method which calls this one
    // on the mock - then you should get an exception as well
}

另外,ClassB 有一个小问题:

public void Object anotherMethod() throws SomeException {
    try {
        // you instantiate obj of type ClassA here
        // which means you cannot mock it if you need
        // to test anotherMethod()
        ClassA objectA = new ClassA(anotherVariable)
        objectA.someMethod()
    } catch {
            // does stuff
    }
}

如果你想测试ClassB.anotherMethod()你需要摆脱这种超紧耦合:

ClassA objectA = new ClassA(anotherVariable)

考虑这样的方法:

public class ClassB {
    private final ClassA objectA;

    public ClassB(ClassA obj) {
        // now you can provide any instance of ClassA instead
        // of having it created in try-block later
        // so when you need ClassB in real code, you can create
        // some real instance of ClassA and pass to this conctructor
        // and for test you can pass mock 
        this.objectA = obj;
    }

    public void Object anotherMethod() throws SomeException {
        try {
            objectA.someMethod()
        } catch {
            // does stuff
        }
    }
}

这给了我们什么:

@Mock
ClassA myObject = new ClassA(obj)

...

@Test(expected = SomeException.class)
public void myTest()throws Exception {
    // stub someMethod on object of ClassA
    doThrow(new SomeException()).when(myObject).someMethod();

    ClassB objB = new ClassB(myObject);
    
    // now you can test it, and inside anotherMethod()
    // there will be a call to someMethod() on a mock
    // so you will get an exception
    objB.anotherMethod();
}

我假设因为你在下面嘲笑 A 类

@Mock
ClassA myObject = new ClassA(obj) //u r creating new instance 

@Mock
ClassA myObject; //assuming u r using initMock or @InjectMocks

或者

ClassA myObject = Mockito.mock(ClassA.class);

然后模拟你如何模拟方法调用的行为

when(myObject.someMethod(any()))
      .thenThrow(new SomeException());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM