android应用程序,java类需要根据NotificationManager的状态执行一些操作。
class Util {
static void setupByPermission(@NonNull final Context appContext) {
Thread t = new Thread(new Runnable() {
public void run() {
try {
NotificationManagerCompat nm = NotificationManagerCompat.from(appContext); // should got from stub
boolean overallPermission = currentNotificationsPermission(nm);
if (overallPermission) {
doWithPermission();
} else {
doWithoutPermission();
}
} catch (Throwable ex) {}
}
});
t.start();
}
static boolean currentNotificationsPermission(@NonNull NotificationManagerCompat nm) {
System.out.println("+++ enter currentNotificationsPermission("+nm+")");
boolean overallPermission = nm.areNotificationsEnabled();// should got result from stub
System.out.println("+++ ========= in currentNotificationsPermission("+nm+"), nm.areNotificationsEnabled() ==> "+overallPermission);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (overallPermission) {
List<NotificationChannel> channels = nm.getNotificationChannels();
boolean someChannelEnabled = channels.isEmpty();
for (NotificationChannel channel : channels) {
if (channel.getImportance() != NotificationManagerCompat.IMPORTANCE_NONE) {
someChannelEnabled = true;
break;
}
}
overallPermission = overallPermission && someChannelEnabled;
}
}
System.out.println("+++ --- exit =========== currentNotificationsPermission(), overallPermission:"+overallPermission);
return overallPermission;
}
}希望存根NotificationManagerCompat.areNotificationsEnabled()以强制测试返回true或false。
使用mockito-inline 3.8.0进行测试
@Test
public void test () throws Exception {
try (MockedStatic<NotificationManagerCompat> nmMoc = Mockito.mockStatic(NotificationManagerCompat.class);
MockedStatic<Util> utilMoc = Mockito.mockStatic(Util.class)
) {
NotificationManagerCompat nmSpy = spy(NotificationManagerCompat.from(application));
when(nmSpy.areNotificationsEnabled())
.thenReturn(false); //or true
nmMoc.when(() -> NotificationManagerCompat.from(any(Context.class)))
.thenReturn(nmSpy);
// test
final CountDownLatch latch = new CountDownLatch(1);
utilMoc.setupByPermission(application);
latch.await(2, TimeUnit.SECONDS);
Mockito.verify(......);
}
}但是当存根在线程中时,存根不会被调用。如果存根currentNotificationsPermission(),也是如此。
让静态函数的存根在线程中工作是不是很热?
发布于 2021-07-12 10:04:01
你的测试似乎有一些问题:
MockedStatic的Javadoc。它显式地告诉你模拟只在原始线程上工作。utilMoc是一个MockedStatic<Util>,所以你如何在它上面调用setupByPermission?Util,在Util上调用方法无论如何都不会调用‘utilMoc’方法,除非你告诉它这样做。参见下面的例子。Runnable的组件。在测试中,使用一个在当前线程上运行Runnable的虚拟实现。import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
public class TestExample {
public static class Foo {
public static String bar() {
return "bar";
}
}
@Test
public void aTest() {
try (MockedStatic<Foo> foo = Mockito.mockStatic(Foo.class)) {
// without this line Foo.bar() will return null
when(Foo.bar()).thenCallRealMethod();
assertThat(Foo.bar()).isEqualTo("bar");
}
}
}虽然人们已经投入了大量的工作来使模拟静态方法成为可能,但正如你所看到的,这仍然不是简单的事情。避免这种情况所需的重构很简单,而且还有其他好处。
https://stackoverflow.com/questions/68340718
复制相似问题