簡體   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