【问题标题】:How can I verify a method is run in a mocked class's callback?如何验证方法在模拟类的回调中运行?
【发布时间】:2018-01-17 19:28:43
【问题描述】:

我的 Android 代码中有一个实用程序类,用于处理用户身份验证。我正在用 Mokcito 为这个类编写单元测试,以验证是否在新用户的创建成功或失败时通知侦听器。这是该实用程序类的方法之一:

public void createNewUser(String email, String password) {
    firebaseAuth.createUserWithEmailAndPassword(email, password)
            .addOnSuccessListener(authResult -> {
                authListener.newUserCreated();
            })
            .addOnFailureListener(e -> {
                authListener.failedCreatingNewUser();
            });
}

我在嘲笑FirebaseAuth,我想验证authListener.newUserCreated() 是否已被调用。我曾尝试使用深度存根和参数捕获器来处理firebaseAuth.createUserWithEmailAndPassword 上的链式方法调用,但我不知道如何让它工作。

更新

这是我测试这个方法的测试类:

public class AuthUtilsTest {

    private static final String USERNAME = "USERNAME";
    private static final String PASSWORD = "PASSWORD";

    @Mock
    private FirebaseAuth firebaseAuth;

    @Mock
    private FirebaseFirestore firebaseFirestore;

    @Mock
    private BaseEncoding base64;

    @Mock
    private PreferencesRepo preferencesRepo;

    @Mock
    private AuthUtilsContract.EventListener eventListener;

    private AuthUtils authUtils;

    @Before
    public void setupAuthUtils() {
        MockitoAnnotations.initMocks(this);

        authUtils = new AuthUtils(
                preferencesRepo,
                firebaseAuth,
                firebaseFirestore,
                base64
        );

        authUtils.takeEventListener(eventListener);
    }

    @Test
    public void failureCreatingNewUserTellsListener() {
        Task<AuthResult> failedTask = Tasks.forException(new Exception("fail"));
        when(firebaseAuth.createUserWithEmailAndPassword(anyString(), anyString())).thenReturn(failedTask);

        authUtils.createNewUser(USERNAME, PASSWORD);

        verify(eventListener).failedCreatingNewUser();
    }

}

抛出异常

java.lang.ExceptionInInitializerError 在 com.google.android.gms.tasks.zzn.addOnSuccessListener(未知来源) ...引起:java.lang.RuntimeException:方法getMainLooper在 android.os.Looper 没有被嘲笑。

【问题讨论】:

    标签: android unit-testing mocking mockito firebase-authentication


    【解决方案1】:

    使用 Mockito.when 使 createUserCall 返回一个模拟任务。 然后在任务上 Mockito.verify 以捕获添加侦听器调用的参数。

    根据您的意愿测试捕获的参数(这就像单元测试中的单元测试,捕获的参数是您正在测试的新类)。

    此方法实际上不会测试是否调用了侦听器。只是调用了添加侦听器方法,并且回调在调用时执行了它们应该做的事情

    verify(mockTask).addOnSuccessListener(listenerCaptor.capture());
    OnSuccessListener<Auth> newObjectUnderTest = listenerCaptor.getValue();
    
    //ACT
    newObjectUnderTest.onSuccess(auth);
    
    //ASSERT
    verify(authListener).newUserCreated();
    

    【讨论】:

    • 你能用这样的代码示例更新你的帖子吗?
    【解决方案2】:

    使用 Mockito.when 使 createUserCall 返回一个已经完成的Task&lt;AuthResult&gt;

    然后 Mockito.verify 验证 authListener 做了它应该假设 authListener 也是一个模拟

    【讨论】:

    • 我已经用我在这个解决方案上的尝试更新了主帖
    猜你喜欢
    • 2017-07-01
    • 1970-01-01
    • 2014-06-08
    • 2014-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    相关资源
    最近更新 更多