简体   繁体   English

Mockito doThrow() 不抛出异常

[英]Mockito doThrow() not throwing exception

There's been similar questions, but none of those can solve my current problem有类似的问题,但没有一个可以解决我目前的问题

Say I have a fairly simple class:假设我有一个相当简单的类:

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

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

Now, I create an instance of this class in a diff class现在,我在 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
        }
    }
}

The end goal is to test the catch block by throwing an exceptions as so最终目标是通过抛出异常来测试 catch 块

@Mock
ClassA myObject = new ClassA(obj)

...

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

For some reason the exceptions is just never thrown.出于某种原因,从未抛出异常。 I've also tried replacing the any() with both valid and invalid objects, and it still doesn't work.我也试过用有效和无效的对象替换any() ,但它仍然不起作用。

Edit1:编辑1:

Whilst fishing for a solution, this for some reason passes the test:在寻找解决方案的同时,由于某种原因,这通过了测试:

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

Any explanation as to why this works?关于为什么这有效的任何解释? Is this bad practice or something?这是不好的做法还是什么?

I believe the reason is that you never call the method:我相信原因是你从不调用该方法:

@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
}

Also, there is a little issue in ClassB:另外,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
    }
}

If you'd like to test ClassB.anotherMethod() you need to get rid of this super tight coupling:如果你想测试ClassB.anotherMethod()你需要摆脱这种超紧耦合:

ClassA objectA = new ClassA(anotherVariable)

Consider approach like this:考虑这样的方法:

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
        }
    }
}

What this gives us:这给了我们什么:

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

I assume since u are mocking Class A below line我假设因为你在下面嘲笑 A 类

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

do

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

or或者

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

then Mock the behavior how u mock a method call然后模拟你如何模拟方法调用的行为

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

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

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