标签: mockito

使用Mockito,如何拦截void方法上的回调对象?

我正在使用mockito来测试遗留的JAAS/LDAP登录模块.

javax.security.auth.callback.CallbackHandler接口定义了功能:

void handle(javax.security.auth.callback.Callback[] callbacks)
Run Code Online (Sandbox Code Playgroud)

我期待callbacks包含一个NameCallback,这是需要操纵以通过测试的对象.

有没有办法有效地模拟这个,或者我会更好地使用存根实现CallbackHandler

java unit-testing callback jaas mockito

28
推荐指数
1
解决办法
1万
查看次数

如何用mockito模拟一个构建器

我有一个建设者:

class Builder{
     private String name;
     private String address;
     public Builder setName(String name){
         this.name = name;
         return this;
    }
     public Builder setAddress(String address){
         this.address = address;
         return this;
    }

}
Run Code Online (Sandbox Code Playgroud)

在mockito中模拟构建器会使每个方法都为null.因此,有一种简单的方法可以让构建器在每次函数调用时返回自己,而不会使用模拟每个函数本身when().thenReturn.

java unit-testing mockito

28
推荐指数
3
解决办法
2万
查看次数

Mockito mock在尝试存根包保护方法时调用实际方法实现

我正在尝试使用Mockito 1.8.5存根方法,但这样做会调用真正的方法实现(使用""作为parm值)会抛出异常.

package background.internal; //located in trunk/tests/java/background/internal

public class MoveStepTest {

    @Test
    public void testMoveUpdate() {
        final String returnValue = "value";
        final FileAttachmentContainer file = mock(FileAttachmentContainer.class);
        doReturn(returnValue).when(file).moveAttachment(anyString(), anyString(), anyString());
        //this also fails
        //when(file.moveAttachment(anyString(), anyString(), anyString())).thenReturn(returnValue);

        final AttachmentMoveStep move = new AttachmentMoveStep(file);
        final Action moveResult = move.advance(1, mock(Context.class));
        assertEquals(Action.done, moveResult);
    }
}
Run Code Online (Sandbox Code Playgroud)

我试图模拟的方法看起来像这样.没有最终的方法或类.

package background.internal; //located in trunk/src/background/internal


   public class FileAttachmentContainer {
        String moveAttachment(final String arg1, final String arg2, final String arg3) 
                throws CustomException {
            ...
        }

        String getPersistedValue(final Context context) …
Run Code Online (Sandbox Code Playgroud)

java mockito

28
推荐指数
1
解决办法
4万
查看次数

通过mockito创建一个模拟列表

我想创建一个模拟列表来测试下面的代码:

 for (String history : list) {
        //code here
    }
Run Code Online (Sandbox Code Playgroud)

这是我的实现:

public static List<String> createList(List<String> mockedList) {

    List<String> list = mock(List.class);
    Iterator<String> iterHistory = mock(Iterator.class);

    OngoingStubbing<Boolean> osBoolean = when(iterHistory.hasNext());
    OngoingStubbing<String> osHistory = when(iterHistory.next());

    for (String history : mockedList) {

        osBoolean = osBoolean.thenReturn(true);
        osHistory = osHistory.thenReturn(history);
    }
    osBoolean = osBoolean.thenReturn(false);

    when(list.iterator()).thenReturn(iterHistory);

    return list;
}
Run Code Online (Sandbox Code Playgroud)

但是当测试运行时,它会在行中抛出异常:

OngoingStubbing<DyActionHistory> osHistory = when(iterHistory.next());
Run Code Online (Sandbox Code Playgroud)

详情:

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
-> at org.powermock.api.mockito.PowerMockito.when(PowerMockito.java:495)

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints: …
Run Code Online (Sandbox Code Playgroud)

java junit unit-testing mocking mockito

28
推荐指数
3
解决办法
11万
查看次数

如何正确窥探活动

当一些东西被监视时,Mockito会创建一个代理实例.现在,有没有办法将在该代理实例上执行的setter转发到它后面的真实实例?

理由:我有一个我完全没有控制的对象实例,即Android活动.我可以给我的应用程序的大部分地区代理的版本和运行正常的是,因为我需要在活动的创建阶段很早就创建间谍/代理,目前尚不能完全实例化,例如基地上下文没附着.这发生在代理实例上,当然不被活动实例本身使用(它通过引用自身Activity.this).最终的结果是,这会导致各种崩溃,因为资源解析是通过这个基础上下文发生的,因此内部Fragment机制会抛出NPE等等.

这是一些代码:

public class CustomAndroidJUnitRunner extends AndroidJUnitRunner {
    @Override
    public Activity newActivity(ClassLoader cl, String className, Intent intent)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        Activity activity = super.newActivity(cl, className, intent);
        return maybeStubSomeDelegate(activity);
    }

    private Activity maybeStubSomeDelegate(Activity activity) {
        if (!(activity instanceof SomeDelegate)) {
            return activity;
        }
        Activity spiedActivity = spy(activity);
        doReturn(SomeDelegateMock.getInstance())
            .when((SomeDelegate) spiedActivity)
            .getDelegate();
        return spiedActivity;
    }
}
Run Code Online (Sandbox Code Playgroud)

我很无能为力 - 任何想法?

android mockito

28
推荐指数
1
解决办法
1578
查看次数

使用PowerMock模拟私有方法,但仍会调用基础方法

我试图嘲笑模拟一个正在进行JNDI调用的私有方法.当从单元测试调用该方法时,它会抛出异常^.我想嘲笑这种方法用于测试目的.我使用了来自另一个问题答案示例代码,并且在测试通过时,似乎仍然调用了基础方法.我System.err.println()doTheGamble()方法中插入了一个,然后打印到我的控制台.

有趣的是,如果我将第一个注释掉assertThat,测试就会通过.?:(

那么,我如何模拟私有方法,以便它不被调用?

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.powermock.api.support.membermodification.MemberMatcher.method;

import java.util.Random;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(CodeWithPrivateMethod.class)
public class PowerMock_Test {

    static boolean gambleCalled = false; 

    @Test(expected = RuntimeException.class)
    public void when_gambling_is_true_then_always_explode() throws Exception {
        CodeWithPrivateMethod spy = PowerMockito.spy(new CodeWithPrivateMethod());

        when(spy, method(CodeWithPrivateMethod.class, "doTheGamble", String.class, int.class))
                .withArguments(anyString(), anyInt())
                .thenReturn(true);

/* 1 */ assertThat( …
Run Code Online (Sandbox Code Playgroud)

java junit mockito powermock

27
推荐指数
1
解决办法
6万
查看次数

每次测试都会重置Mock对象吗?

我正在使用Mockito框架在我的JUnit测试中创建Mock对象.每个模拟器都知道调用了哪些方法,所以在我的测试中我可以编写

verify(myMock, atLeastOnce()).myMethod();
Run Code Online (Sandbox Code Playgroud)

我想知道这个内部的模拟知识是否会在我的测试中持续存在?如果它确实存在,那么当我verify在两个测试中使用相同的方法时,我可能会得到误报.

一个代码示例

@RunWith(MockitoJUnitRunner.class)
public class EmrActivitiesImplTest {

    @Mock private MyClass myMock;

    @Before
    public void setup() {
        when(myMock.myMethod()).thenReturn("hello");
    }

    @Test
    public void test1() {
        // ..some logic
        verify(myMock, atLeastOnce()).myMethod();
    }

    @Test
    public void test2() {
        // ..some other logic
        verify(myMock, atLeastOnce()).myMethod();
    }  
}
Run Code Online (Sandbox Code Playgroud)

模拟状态是持久的 - test2将通过,因为test1的验证方法已通过

模拟状态被重置 - 如果未调用myMock.myMethod(),test2将失败

java junit mockito

27
推荐指数
2
解决办法
3万
查看次数

使用mockito模拟嵌套方法调用

我有4个类让我们说A,B,C,D各自调用另一个类的方法.

现在我嘲笑了A类,想要使用mockito模拟一个方法

A a = Mockito.mock(A.class);
Run Code Online (Sandbox Code Playgroud)

并希望在递归方法调用上得到"foo"

a.getB().getC().getD() 应该回来 "foo"

我试过了

当(a.getB()GETC()GETD().)thenReturn( "foo" 的).

但得到了nullPointerException

然后我试了

doReturn( "富")时(a.getB()GETC()GETD()...).;

然后我得到了 org.mockito.exceptions.misusing.UnfinishedStubbingException:

我知道我可以创建B,C和D的对象,或者甚至可以写出类似的东西

B b = mock(B.class)或A.setB(new B())

等等.

但我不能一次性做到这一点?任何帮助,将不胜感激.

java methods junit mocking mockito

27
推荐指数
3
解决办法
2万
查看次数

ArgumentMatchers.any 不能为空

我正在尝试测试ViewModel以确保 livedata 正确更新。但是,当使用ArgumentMatchers.any()它失败时IllegalStateException说:

ArgumentMatchers.any(mViewModel.CountSubscriber::class.java) 不能为空

@Test
fun emitValueIfCountIs7() {
    doAnswer { invocation: InvocationOnMock ->
        val subscriber: mViewModel.CountSubscriber = invocation.getArgument(0)
        subscriber.onNext(7)
        null
    }.`when`(countUseCase).execute(
        ArgumentMatchers.any(mViewModel.CountSubscriber::class.java),
        ArgumentMatchers.any(Parameters::class.java)
    )
    
    // When
    mViewModel.getCount()
    
    // Verify
    assert(mViewModel.countResponse.value != null)
}
Run Code Online (Sandbox Code Playgroud)

我正在使用 Kotlin 并具有以下依赖项:

testImplementation 'junit:junit:4.12'
testImplementation "org.mockito:mockito-inline:2.23.4"
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0"
Run Code Online (Sandbox Code Playgroud)

这是我的进口:

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.nhaarman.mockitokotlin2.doAnswer
import io.reactivex.Observable
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.ArgumentMatchers.any
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.MockitoAnnotations
import org.mockito.invocation.InvocationOnMock
Run Code Online (Sandbox Code Playgroud)

奇怪的是它以前可以工作,我不知道发生了什么可能会影响它。

android unit-testing mockito viewmodel kotlin

27
推荐指数
4
解决办法
1万
查看次数

是否可以在PowerMock中对私有静态方法使用部分模拟?

PowerMock主页上的示例中,我看到以下示例,用于部分模拟Mockito的私有方法:

@RunWith(PowerMockRunner.class)
// We prepare PartialMockClass for test because it's final or we need to mock private or static methods
@PrepareForTest(PartialMockClass.class)
public class YourTestCase {
@Test
public void privatePartialMockingWithPowerMock() {        
    PartialMockClass classUnderTest = PowerMockito.spy(new PartialMockClass());

    // use PowerMockito to set up your expectation
    PowerMockito.doReturn(value).when(classUnderTest, "methodToMock", "parameter1");

    // execute your test
    classUnderTest.execute();

    // Use PowerMockito.verify() to verify result
    PowerMockito.verifyPrivate(classUnderTest, times(2)).invoke("methodToMock", "parameter1");
}
Run Code Online (Sandbox Code Playgroud)

但是,当我们希望模拟的私有方法是静态的时,这种方法似乎不起作用.我希望创建一个以下类的部分模拟,并使用readFile方法进行模拟:

package org.rich.powermockexample;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;

import static com.google.common.io.Files.readLines;

public class DataProvider …
Run Code Online (Sandbox Code Playgroud)

java unit-testing mockito powermock

26
推荐指数
2
解决办法
2万
查看次数