Best Mockito code snippet using org.mockito.internal.creation.bytebuddy.MockMethodAdvice.handleStatic
Source:MockMethodAdvice.java  
...138                        realMethod,139                        new LocationImpl(new Throwable(), true)));140    }141    @Override142    public Callable<?> handleStatic(Class<?> type, Method origin, Object[] arguments)143            throws Throwable {144        Map<Class<?>, MockMethodInterceptor> interceptors = mockedStatics.get();145        if (interceptors == null || !interceptors.containsKey(type)) {146            return null;147        }148        return new ReturnValueWrapper(149                interceptors150                        .get(type)151                        .doIntercept(152                                type,153                                origin,154                                arguments,155                                new StaticMethodCall(selfCallInfo, type, origin, arguments),156                                new LocationImpl(new Throwable(), true)));157    }158    @Override159    public Object handleConstruction(160            Class<?> type, Object object, Object[] arguments, String[] parameterTypeNames) {161        return onConstruction.apply(type, object, arguments, parameterTypeNames);162    }163    @Override164    public boolean isMock(Object instance) {165        // We need to exclude 'interceptors.target' explicitly to avoid a recursive check on whether166        // the map is a mock object what requires reading from the map.167        return instance != interceptors.target && interceptors.containsKey(instance);168    }169    @Override170    public boolean isMocked(Object instance) {171        return selfCallInfo.checkSelfCall(instance) && isMock(instance);172    }173    @Override174    public boolean isMockedStatic(Class<?> type) {175        if (!selfCallInfo.checkSelfCall(type)) {176            return false;177        }178        Map<Class<?>, ?> interceptors = mockedStatics.get();179        return interceptors != null && interceptors.containsKey(type);180    }181    @Override182    public boolean isOverridden(Object instance, Method origin) {183        SoftReference<MethodGraph> reference = graphs.get(instance.getClass());184        MethodGraph methodGraph = reference == null ? null : reference.get();185        if (methodGraph == null) {186            methodGraph = compiler.compile(new TypeDescription.ForLoadedType(instance.getClass()));187            graphs.put(instance.getClass(), new SoftReference<MethodGraph>(methodGraph));188        }189        MethodGraph.Node node =190                methodGraph.locate(191                        new MethodDescription.ForLoadedMethod(origin).asSignatureToken());192        return !node.getSort().isResolved()193                || !node.getRepresentative()194                        .asDefined()195                        .getDeclaringType()196                        .represents(origin.getDeclaringClass());197    }198    @Override199    public boolean isConstructorMock(Class<?> type) {200        return isMockConstruction.test(type);201    }202    private static class RealMethodCall implements RealMethod {203        private final SelfCallInfo selfCallInfo;204        private final Method origin;205        private final MockWeakReference<Object> instanceRef;206        private final Object[] arguments;207        private RealMethodCall(208                SelfCallInfo selfCallInfo, Method origin, Object instance, Object[] arguments) {209            this.selfCallInfo = selfCallInfo;210            this.origin = origin;211            this.instanceRef = new MockWeakReference<Object>(instance);212            this.arguments = arguments;213        }214        @Override215        public boolean isInvokable() {216            return true;217        }218        @Override219        public Object invoke() throws Throwable {220            selfCallInfo.set(instanceRef.get());221            return tryInvoke(origin, instanceRef.get(), arguments);222        }223    }224    private static class SerializableRealMethodCall implements RealMethod {225        private final String identifier;226        private final SerializableMethod origin;227        private final MockReference<Object> instanceRef;228        private final Object[] arguments;229        private SerializableRealMethodCall(230                String identifier, Method origin, Object instance, Object[] arguments) {231            this.origin = new SerializableMethod(origin);232            this.identifier = identifier;233            this.instanceRef = new MockWeakReference<Object>(instance);234            this.arguments = arguments;235        }236        @Override237        public boolean isInvokable() {238            return true;239        }240        @Override241        public Object invoke() throws Throwable {242            Method method = origin.getJavaMethod();243            MockMethodDispatcher mockMethodDispatcher =244                    MockMethodDispatcher.get(identifier, instanceRef.get());245            if (!(mockMethodDispatcher instanceof MockMethodAdvice)) {246                throw new MockitoException("Unexpected dispatcher for advice-based super call");247            }248            Object previous =249                    ((MockMethodAdvice) mockMethodDispatcher)250                            .selfCallInfo.replace(instanceRef.get());251            try {252                return tryInvoke(method, instanceRef.get(), arguments);253            } finally {254                ((MockMethodAdvice) mockMethodDispatcher).selfCallInfo.set(previous);255            }256        }257    }258    private static class StaticMethodCall implements RealMethod {259        private final SelfCallInfo selfCallInfo;260        private final Class<?> type;261        private final Method origin;262        private final Object[] arguments;263        private StaticMethodCall(264                SelfCallInfo selfCallInfo, Class<?> type, Method origin, Object[] arguments) {265            this.selfCallInfo = selfCallInfo;266            this.type = type;267            this.origin = origin;268            this.arguments = arguments;269        }270        @Override271        public boolean isInvokable() {272            return true;273        }274        @Override275        public Object invoke() throws Throwable {276            selfCallInfo.set(type);277            return tryInvoke(origin, null, arguments);278        }279    }280    private static Object tryInvoke(Method origin, Object instance, Object[] arguments)281            throws Throwable {282        MemberAccessor accessor = Plugins.getMemberAccessor();283        try {284            return accessor.invoke(origin, instance, arguments);285        } catch (InvocationTargetException exception) {286            Throwable cause = exception.getCause();287            new ConditionalStackTraceFilter()288                    .filter(289                            hideRecursiveCall(290                                    cause,291                                    new Throwable().getStackTrace().length,292                                    origin.getDeclaringClass()));293            throw cause;294        }295    }296    private static class ReturnValueWrapper implements Callable<Object> {297        private final Object returned;298        private ReturnValueWrapper(Object returned) {299            this.returned = returned;300        }301        @Override302        public Object call() {303            return returned;304        }305    }306    private static class SelfCallInfo extends ThreadLocal<Object> {307        Object replace(Object value) {308            Object current = get();309            set(value);310            return current;311        }312        boolean checkSelfCall(Object value) {313            if (value == get()) {314                set(null);315                return false;316            } else {317                return true;318            }319        }320    }321    static class ConstructorShortcut322            implements AsmVisitorWrapper.ForDeclaredMethods.MethodVisitorWrapper {323        private final String identifier;324        ConstructorShortcut(String identifier) {325            this.identifier = identifier;326        }327        @Override328        public MethodVisitor wrap(329                TypeDescription instrumentedType,330                MethodDescription instrumentedMethod,331                MethodVisitor methodVisitor,332                Implementation.Context implementationContext,333                TypePool typePool,334                int writerFlags,335                int readerFlags) {336            if (instrumentedMethod.isConstructor() && !instrumentedType.represents(Object.class)) {337                MethodList<MethodDescription.InDefinedShape> constructors =338                        instrumentedType339                                .getSuperClass()340                                .asErasure()341                                .getDeclaredMethods()342                                .filter(isConstructor().and(not(isPrivate())));343                int arguments = Integer.MAX_VALUE;344                boolean packagePrivate = true;345                MethodDescription.InDefinedShape current = null;346                for (MethodDescription.InDefinedShape constructor : constructors) {347                    // We are choosing the shortest constructor with regards to arguments.348                    // Yet, we prefer a non-package-private constructor since they require349                    // the super class to be on the same class loader.350                    if (constructor.getParameters().size() < arguments351                            && (packagePrivate || !constructor.isPackagePrivate())) {352                        arguments = constructor.getParameters().size();353                        packagePrivate = constructor.isPackagePrivate();354                        current = constructor;355                    }356                }357                if (current != null) {358                    final MethodDescription.InDefinedShape selected = current;359                    return new MethodVisitor(OpenedClassReader.ASM_API, methodVisitor) {360                        @Override361                        public void visitCode() {362                            super.visitCode();363                            /*364                             * The byte code that is added to the start of the method is roughly equivalent to365                             * the following byte code for a hypothetical constructor of class Current:366                             *367                             * if (MockMethodDispatcher.isConstructorMock(<identifier>, Current.class) {368                             *   super(<default arguments>);369                             *   Current o = (Current) MockMethodDispatcher.handleConstruction(Current.class,370                             *       this,371                             *       new Object[] {argument1, argument2, ...},372                             *       new String[] {argumentType1, argumentType2, ...});373                             *   if (o != null) {374                             *     this.field = o.field; // for each declared field375                             *   }376                             *   return;377                             * }378                             *379                             * This avoids the invocation of the original constructor chain but fullfils the380                             * verifier requirement to invoke a super constructor.381                             */382                            Label label = new Label();383                            super.visitLdcInsn(identifier);384                            if (implementationContext385                                    .getClassFileVersion()386                                    .isAtLeast(ClassFileVersion.JAVA_V5)) {387                                super.visitLdcInsn(Type.getType(instrumentedType.getDescriptor()));388                            } else {389                                super.visitLdcInsn(instrumentedType.getName());390                                super.visitMethodInsn(391                                        Opcodes.INVOKESTATIC,392                                        Type.getInternalName(Class.class),393                                        "forName",394                                        Type.getMethodDescriptor(395                                                Type.getType(Class.class),396                                                Type.getType(String.class)),397                                        false);398                            }399                            super.visitMethodInsn(400                                    Opcodes.INVOKESTATIC,401                                    Type.getInternalName(MockMethodDispatcher.class),402                                    "isConstructorMock",403                                    Type.getMethodDescriptor(404                                            Type.BOOLEAN_TYPE,405                                            Type.getType(String.class),406                                            Type.getType(Class.class)),407                                    false);408                            super.visitInsn(Opcodes.ICONST_0);409                            super.visitJumpInsn(Opcodes.IF_ICMPEQ, label);410                            super.visitVarInsn(Opcodes.ALOAD, 0);411                            for (TypeDescription type :412                                    selected.getParameters().asTypeList().asErasures()) {413                                if (type.represents(boolean.class)414                                        || type.represents(byte.class)415                                        || type.represents(short.class)416                                        || type.represents(char.class)417                                        || type.represents(int.class)) {418                                    super.visitInsn(Opcodes.ICONST_0);419                                } else if (type.represents(long.class)) {420                                    super.visitInsn(Opcodes.LCONST_0);421                                } else if (type.represents(float.class)) {422                                    super.visitInsn(Opcodes.FCONST_0);423                                } else if (type.represents(double.class)) {424                                    super.visitInsn(Opcodes.DCONST_0);425                                } else {426                                    super.visitInsn(Opcodes.ACONST_NULL);427                                }428                            }429                            super.visitMethodInsn(430                                    Opcodes.INVOKESPECIAL,431                                    selected.getDeclaringType().getInternalName(),432                                    selected.getInternalName(),433                                    selected.getDescriptor(),434                                    false);435                            super.visitLdcInsn(identifier);436                            if (implementationContext437                                    .getClassFileVersion()438                                    .isAtLeast(ClassFileVersion.JAVA_V5)) {439                                super.visitLdcInsn(Type.getType(instrumentedType.getDescriptor()));440                            } else {441                                super.visitLdcInsn(instrumentedType.getName());442                                super.visitMethodInsn(443                                        Opcodes.INVOKESTATIC,444                                        Type.getInternalName(Class.class),445                                        "forName",446                                        Type.getMethodDescriptor(447                                                Type.getType(Class.class),448                                                Type.getType(String.class)),449                                        false);450                            }451                            super.visitVarInsn(Opcodes.ALOAD, 0);452                            super.visitLdcInsn(instrumentedMethod.getParameters().size());453                            super.visitTypeInsn(454                                    Opcodes.ANEWARRAY, Type.getInternalName(Object.class));455                            int index = 0;456                            for (ParameterDescription parameter :457                                    instrumentedMethod.getParameters()) {458                                super.visitInsn(Opcodes.DUP);459                                super.visitLdcInsn(index++);460                                Type type =461                                        Type.getType(462                                                parameter.getType().asErasure().getDescriptor());463                                super.visitVarInsn(464                                        type.getOpcode(Opcodes.ILOAD), parameter.getOffset());465                                if (parameter.getType().isPrimitive()) {466                                    Type wrapper =467                                            Type.getType(468                                                    parameter469                                                            .getType()470                                                            .asErasure()471                                                            .asBoxed()472                                                            .getDescriptor());473                                    super.visitMethodInsn(474                                            Opcodes.INVOKESTATIC,475                                            wrapper.getInternalName(),476                                            "valueOf",477                                            Type.getMethodDescriptor(wrapper, type),478                                            false);479                                }480                                super.visitInsn(Opcodes.AASTORE);481                            }482                            index = 0;483                            super.visitLdcInsn(instrumentedMethod.getParameters().size());484                            super.visitTypeInsn(485                                    Opcodes.ANEWARRAY, Type.getInternalName(String.class));486                            for (TypeDescription typeDescription :487                                    instrumentedMethod.getParameters().asTypeList().asErasures()) {488                                super.visitInsn(Opcodes.DUP);489                                super.visitLdcInsn(index++);490                                super.visitLdcInsn(typeDescription.getName());491                                super.visitInsn(Opcodes.AASTORE);492                            }493                            super.visitMethodInsn(494                                    Opcodes.INVOKESTATIC,495                                    Type.getInternalName(MockMethodDispatcher.class),496                                    "handleConstruction",497                                    Type.getMethodDescriptor(498                                            Type.getType(Object.class),499                                            Type.getType(String.class),500                                            Type.getType(Class.class),501                                            Type.getType(Object.class),502                                            Type.getType(Object[].class),503                                            Type.getType(String[].class)),504                                    false);505                            FieldList<FieldDescription.InDefinedShape> fields =506                                    instrumentedType.getDeclaredFields().filter(not(isStatic()));507                            super.visitTypeInsn(508                                    Opcodes.CHECKCAST, instrumentedType.getInternalName());509                            super.visitInsn(Opcodes.DUP);510                            Label noSpy = new Label();511                            super.visitJumpInsn(Opcodes.IFNULL, noSpy);512                            for (FieldDescription field : fields) {513                                super.visitInsn(Opcodes.DUP);514                                super.visitFieldInsn(515                                        Opcodes.GETFIELD,516                                        instrumentedType.getInternalName(),517                                        field.getInternalName(),518                                        field.getDescriptor());519                                super.visitVarInsn(Opcodes.ALOAD, 0);520                                super.visitInsn(521                                        field.getType().getStackSize() == StackSize.DOUBLE522                                                ? Opcodes.DUP_X2523                                                : Opcodes.DUP_X1);524                                super.visitInsn(Opcodes.POP);525                                super.visitFieldInsn(526                                        Opcodes.PUTFIELD,527                                        instrumentedType.getInternalName(),528                                        field.getInternalName(),529                                        field.getDescriptor());530                            }531                            super.visitLabel(noSpy);532                            if (implementationContext533                                    .getClassFileVersion()534                                    .isAtLeast(ClassFileVersion.JAVA_V6)) {535                                Object[] locals =536                                        toFrames(537                                                instrumentedType.getInternalName(),538                                                instrumentedMethod539                                                        .getParameters()540                                                        .asTypeList()541                                                        .asErasures());542                                super.visitFrame(543                                        Opcodes.F_FULL,544                                        locals.length,545                                        locals,546                                        1,547                                        new Object[] {instrumentedType.getInternalName()});548                            }549                            super.visitInsn(Opcodes.POP);550                            super.visitInsn(Opcodes.RETURN);551                            super.visitLabel(label);552                            if (implementationContext553                                    .getClassFileVersion()554                                    .isAtLeast(ClassFileVersion.JAVA_V6)) {555                                Object[] locals =556                                        toFrames(557                                                Opcodes.UNINITIALIZED_THIS,558                                                instrumentedMethod559                                                        .getParameters()560                                                        .asTypeList()561                                                        .asErasures());562                                super.visitFrame(563                                        Opcodes.F_FULL, locals.length, locals, 0, new Object[0]);564                            }565                        }566                        @Override567                        public void visitMaxs(int maxStack, int maxLocals) {568                            int prequel = Math.max(5, selected.getStackSize());569                            for (ParameterDescription parameter :570                                    instrumentedMethod.getParameters()) {571                                prequel =572                                        Math.max(573                                                prequel,574                                                6 + parameter.getType().getStackSize().getSize());575                                prequel = Math.max(prequel, 8);576                            }577                            super.visitMaxs(Math.max(maxStack, prequel), maxLocals);578                        }579                    };580                }581            }582            return methodVisitor;583        }584        private static Object[] toFrames(Object self, List<TypeDescription> types) {585            Object[] frames = new Object[1 + types.size()];586            frames[0] = self;587            int index = 0;588            for (TypeDescription type : types) {589                Object frame;590                if (type.represents(boolean.class)591                        || type.represents(byte.class)592                        || type.represents(short.class)593                        || type.represents(char.class)594                        || type.represents(int.class)) {595                    frame = Opcodes.INTEGER;596                } else if (type.represents(long.class)) {597                    frame = Opcodes.LONG;598                } else if (type.represents(float.class)) {599                    frame = Opcodes.FLOAT;600                } else if (type.represents(double.class)) {601                    frame = Opcodes.DOUBLE;602                } else {603                    frame = type.getInternalName();604                }605                frames[++index] = frame;606            }607            return frames;608        }609    }610    @Retention(RetentionPolicy.RUNTIME)611    @interface Identifier {}612    static class ForHashCode {613        @SuppressWarnings("unused")614        @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)615        private static boolean enter(@Identifier String id, @Advice.This Object self) {616            MockMethodDispatcher dispatcher = MockMethodDispatcher.get(id, self);617            return dispatcher != null && dispatcher.isMock(self);618        }619        @SuppressWarnings({"unused", "UnusedAssignment"})620        @Advice.OnMethodExit621        private static void enter(622                @Advice.This Object self,623                @Advice.Return(readOnly = false) int hashCode,624                @Advice.Enter boolean skipped) {625            if (skipped) {626                hashCode = System.identityHashCode(self);627            }628        }629    }630    static class ForEquals {631        @SuppressWarnings("unused")632        @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)633        private static boolean enter(@Identifier String identifier, @Advice.This Object self) {634            MockMethodDispatcher dispatcher = MockMethodDispatcher.get(identifier, self);635            return dispatcher != null && dispatcher.isMock(self);636        }637        @SuppressWarnings({"unused", "UnusedAssignment"})638        @Advice.OnMethodExit639        private static void enter(640                @Advice.This Object self,641                @Advice.Argument(0) Object other,642                @Advice.Return(readOnly = false) boolean equals,643                @Advice.Enter boolean skipped) {644            if (skipped) {645                equals = self == other;646            }647        }648    }649    static class ForStatic {650        @SuppressWarnings("unused")651        @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)652        private static Callable<?> enter(653                @Identifier String identifier,654                @Advice.Origin Class<?> type,655                @Advice.Origin Method origin,656                @Advice.AllArguments Object[] arguments)657                throws Throwable {658            MockMethodDispatcher dispatcher = MockMethodDispatcher.getStatic(identifier, type);659            if (dispatcher == null || !dispatcher.isMockedStatic(type)) {660                return null;661            } else {662                return dispatcher.handleStatic(type, origin, arguments);663            }664        }665        @SuppressWarnings({"unused", "UnusedAssignment"})666        @Advice.OnMethodExit667        private static void exit(668                @Advice.Return(readOnly = false, typing = Assigner.Typing.DYNAMIC) Object returned,669                @Advice.Enter Callable<?> mocked)670                throws Throwable {671            if (mocked != null) {672                returned = mocked.call();673            }674        }675    }676    public static class ForReadObject {...handleStatic
Using AI Code Generation
1import org.mockito.internal.creation.bytebuddy.MockMethodAdvice2import org.mockito.internal.creation.bytebuddy.MockMethodInterceptor3import org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.Dispatcher4import org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.Dispatcher.Default5import org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.Dispatcher.NullDispatcher6import org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.MockAccess7import org.mockito.internal.creation.bytebuddy.MockMethodInterceptor.SerializableMockAccess8import org.mockito.internal.creation.bytebuddy.TypeCachingByteBuddyMockMaker9import org.mockito.internal.invocation.MockHandler10import org.mockito.internal.util.MockUtil11import org.mockito.invocation.InvocationOnMock12import org.mockito.mock.MockCreationSettings13import org.mockito.plugins.MockMaker14import org.mockito.stubbing.Answer15import org.mockito.stubbing.Stubber16import org.mockito.verification.VerificationMode17import org.objenesis.Objenesis18import org.objenesis.ObjenesisStd19import org.objenesis.instantiator.ObjectInstantiator20import java.io.ObjectStreamException21import java.lang.reflect.Method22import java.util.concurrent.ConcurrentHashMap23import net.bytebuddy.ByteBuddy24import net.bytebuddy.description.modifier.Visibility25import net.bytebuddy.dynamic.DynamicType26import net.bytebuddy.dynamic.loading.ClassLoadingStrategy27import net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default.WRAPPER28import net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default.WRAPPER_PERSISTENT29import net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default.WRAPPER_PERSISTENT_CACHE30import net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default.WRAPPER_PERSISTENT_CACHE_CONCURRENT31import net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default.WRAPPER_PERSISTENT_CONCURRENT32import net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default.WRAPPER_PERSISTENT_CONCURRENT_DISALLOWED33import net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default.WRAPPER_PERSISTENT_DISALLOWED34import net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default.WRAPPER_PERSISTENT_DISALLOWED_CONCURRENT35import net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default.WRAPPER_PERSISTENT_DISALLOWED_CONCURRENT_DISALLOWED36import net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default.WRAPPER_PERSISTENT_DISALLOWED_DISALLOWED37import net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default.WRAPPER_PERSISTENT_DISALLOWED_DISALLOWED_CONhandleStatic
Using AI Code Generation
1public class MockMethodAdvice {2    public static Object handleStatic(Method method, Object[] args) throws Throwable {3        return null;4    }5}6public class MockMethodAdvice {7    public Object handle(Method method, Object[] args) throws Throwable {8        return null;9    }10}handleStatic
Using AI Code Generation
1import org.mockito.internal.creation.bytebuddy.MockMethodAdvice2import org.mockito.internal.creation.bytebuddy.MockMethodAdvice.handleStatic3public class MyTest {4  public void test() {5    handleStatic("hello")6  }7}8import org.mockito.internal.creation.bytebuddy.MockMethodAdvice9import org.mockito.internal.creation.bytebuddy.MockMethodAdvice.handleStatic10class A {11    static String foo() {12    }13}14class B {15    static String foo() {16    }17}18class C {19    static String foo() {20    }21}22class D {23    static String foo() {24    }25}26class E {27    static String foo() {28    }29}30class F {31    static String foo() {32    }33}34class G {35    static String foo() {36    }37}38class H {39    static String foo() {40    }41}42class I {43    static String foo() {44    }45}46class J {47    static String foo() {48    }49}50class K {51    static String foo() {52    }53}54class L {55    static String foo() {56    }57}58class M {59    static String foo() {60    }61}62class N {63    static String foo() {64    }65}66class O {67    static String foo() {68    }69}70class P {71    static String foo() {72    }73}74class Q {75    static String foo() {76    }77}78class R {79    static String foo() {80    }81}82class S {83    static String foo() {84    }85}86class T {87    static String foo() {88    }89}90class U {91    static String foo() {92    }Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
