Best Mockito code snippet using org.mockito.codegen.InjectionBase.InjectionBase
Source:ModuleHandler.java
...12import net.bytebuddy.implementation.StubMethod;13import net.bytebuddy.utility.GraalImageCode;14import net.bytebuddy.utility.RandomString;15import org.mockito.Mockito;16import org.mockito.codegen.InjectionBase;17import org.mockito.exceptions.base.MockitoException;18import java.lang.reflect.Field;19import java.lang.reflect.Method;20import static net.bytebuddy.matcher.ElementMatchers.isTypeInitializer;21import static org.mockito.internal.util.StringUtil.join;22abstract class ModuleHandler {23 abstract boolean isOpened(Class<?> source, Class<?> target);24 abstract boolean canRead(Class<?> source, Class<?> target);25 abstract boolean isExported(Class<?> source);26 abstract boolean isExported(Class<?> source, Class<?> target);27 abstract Class<?> injectionBase(ClassLoader classLoader, String tyoeName);28 abstract void adjustModuleGraph(Class<?> source, Class<?> target, boolean export, boolean read);29 static ModuleHandler make(ByteBuddy byteBuddy, SubclassLoader loader) {30 try {31 return new ModuleSystemFound(byteBuddy, loader);32 } catch (Exception ignored) {33 return new NoModuleSystemFound();34 }35 }36 private static class ModuleSystemFound extends ModuleHandler {37 private final ByteBuddy byteBuddy;38 private final SubclassLoader loader;39 private final int injectonBaseSuffix;40 private final Method getModule,41 isOpen,42 isExported,43 isExportedUnqualified,44 canRead,45 addExports,46 addReads,47 forName;48 private ModuleSystemFound(ByteBuddy byteBuddy, SubclassLoader loader) throws Exception {49 this.byteBuddy = byteBuddy;50 this.loader = loader;51 injectonBaseSuffix =52 GraalImageCode.getCurrent().isDefined()53 ? 054 : Math.abs(Mockito.class.hashCode());55 Class<?> moduleType = Class.forName("java.lang.Module");56 getModule = Class.class.getMethod("getModule");57 isOpen = moduleType.getMethod("isOpen", String.class, moduleType);58 isExported = moduleType.getMethod("isExported", String.class, moduleType);59 isExportedUnqualified = moduleType.getMethod("isExported", String.class);60 canRead = moduleType.getMethod("canRead", moduleType);61 addExports = moduleType.getMethod("addExports", String.class, moduleType);62 addReads = moduleType.getMethod("addReads", moduleType);63 forName = Class.class.getMethod("forName", String.class);64 }65 @Override66 boolean isOpened(Class<?> source, Class<?> target) {67 if (source.getPackage() == null) {68 return true;69 }70 return (Boolean)71 invoke(72 isOpen,73 invoke(getModule, source),74 source.getPackage().getName(),75 invoke(getModule, target));76 }77 @Override78 boolean canRead(Class<?> source, Class<?> target) {79 return (Boolean) invoke(canRead, invoke(getModule, source), invoke(getModule, target));80 }81 @Override82 boolean isExported(Class<?> source) {83 if (source.getPackage() == null) {84 return true;85 }86 return (Boolean)87 invoke(88 isExportedUnqualified,89 invoke(getModule, source),90 source.getPackage().getName());91 }92 @Override93 boolean isExported(Class<?> source, Class<?> target) {94 if (source.getPackage() == null) {95 return true;96 }97 return (Boolean)98 invoke(99 isExported,100 invoke(getModule, source),101 source.getPackage().getName(),102 invoke(getModule, target));103 }104 @Override105 Class<?> injectionBase(ClassLoader classLoader, String typeName) {106 String packageName = typeName.substring(0, typeName.lastIndexOf('.'));107 if (classLoader == InjectionBase.class.getClassLoader()108 && InjectionBase.class.getPackage().getName().equals(packageName)) {109 return InjectionBase.class;110 } else {111 synchronized (this) {112 String name;113 int suffix = injectonBaseSuffix;114 do {115 name =116 packageName117 + "."118 + InjectionBase.class.getSimpleName()119 + "$"120 + suffix++;121 try {122 Class<?> type = Class.forName(name, false, classLoader);123 // The injected type must be defined in the class loader that is target124 // of the injection. Otherwise,125 // the class's unnamed module would differ from the intended module. To126 // avoid conflicts, we increment127 // the suffix until we hit a class with a known name and generate one if128 // it does not exist.129 if (type.getClassLoader() == classLoader) {130 return type;131 }132 } catch (ClassNotFoundException ignored) {133 break;134 }135 } while (true);136 return byteBuddy137 .subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)138 .name(name)139 .make()140 .load(141 classLoader,142 loader.resolveStrategy(InjectionBase.class, classLoader, false))143 .getLoaded();144 }145 }146 }147 @Override148 void adjustModuleGraph(Class<?> source, Class<?> target, boolean export, boolean read) {149 boolean needsExport = export && !isExported(source, target);150 boolean needsRead = read && !canRead(source, target);151 if (!needsExport && !needsRead) {152 return;153 }154 ClassLoader classLoader = source.getClassLoader();155 if (classLoader == null) {156 throw new MockitoException(157 join(158 "Cannot adjust module graph for modules in the bootstrap loader",159 "",160 source161 + " is declared by the bootstrap loader and cannot be adjusted",162 "Requires package export to " + target + ": " + needsExport,163 "Requires adjusted reading of " + target + ": " + needsRead));164 }165 boolean targetVisible = classLoader == target.getClassLoader();166 while (!targetVisible && classLoader != null) {167 classLoader = classLoader.getParent();168 targetVisible = classLoader == target.getClassLoader();169 }170 MethodCall targetLookup;171 Implementation.Composable implementation;172 if (targetVisible) {173 targetLookup =174 MethodCall.invoke(getModule)175 .onMethodCall(MethodCall.invoke(forName).with(target.getName()));176 implementation = StubMethod.INSTANCE;177 } else {178 Class<?> intermediate;179 Field field;180 try {181 intermediate =182 byteBuddy183 .subclass(184 Object.class,185 ConstructorStrategy.Default.NO_CONSTRUCTORS)186 .name(187 String.format(188 "%s$%s%s",189 "org.mockito.codegen.MockitoTypeCarrier",190 RandomString.hashOf(191 source.getName().hashCode()),192 RandomString.hashOf(193 target.getName().hashCode())))194 .defineField(195 "mockitoType",196 Class.class,197 Visibility.PUBLIC,198 Ownership.STATIC)199 .make()200 .load(201 source.getClassLoader(),202 loader.resolveStrategy(203 source, source.getClassLoader(), false))204 .getLoaded();205 field = intermediate.getField("mockitoType");206 field.set(null, target);207 } catch (Exception e) {208 throw new MockitoException(209 join(210 "Could not create a carrier for making the Mockito type visible to "211 + source,212 "",213 "This is required to adjust the module graph to enable mock creation"),214 e);215 }216 targetLookup = MethodCall.invoke(getModule).onField(field);217 implementation =218 MethodCall.invoke(getModule)219 .onMethodCall(220 MethodCall.invoke(forName).with(intermediate.getName()));221 }222 MethodCall sourceLookup =223 MethodCall.invoke(getModule)224 .onMethodCall(MethodCall.invoke(forName).with(source.getName()));225 if (needsExport) {226 implementation =227 implementation.andThen(228 MethodCall.invoke(addExports)229 .onMethodCall(sourceLookup)230 .with(target.getPackage().getName())231 .withMethodCall(targetLookup));232 }233 if (needsRead) {234 implementation =235 implementation.andThen(236 MethodCall.invoke(addReads)237 .onMethodCall(sourceLookup)238 .withMethodCall(targetLookup));239 }240 try {241 Class.forName(242 byteBuddy243 .subclass(Object.class)244 .name(245 String.format(246 "%s$%s$%s%s",247 source.getName(),248 "MockitoModuleProbe",249 RandomString.hashOf(source.getName().hashCode()),250 RandomString.hashOf(target.getName().hashCode())))251 .invokable(isTypeInitializer())252 .intercept(implementation)253 .make()254 .load(255 source.getClassLoader(),256 loader.resolveStrategy(257 source, source.getClassLoader(), false))258 .getLoaded()259 .getName(),260 true,261 source.getClassLoader());262 } catch (Exception e) {263 throw new MockitoException(264 join(265 "Could not force module adjustment of the module of " + source,266 "",267 "This is required to adjust the module graph to enable mock creation"),268 e);269 }270 }271 private static Object invoke(Method method, Object target, Object... args) {272 try {273 return method.invoke(target, args);274 } catch (Exception e) {275 throw new MockitoException(276 join(277 "Could not invoke " + method + " using reflection",278 "",279 "Mockito attempted to interact with the Java module system but an unexpected method behavior was encountered"),280 e);281 }282 }283 }284 private static class NoModuleSystemFound extends ModuleHandler {285 @Override286 boolean isOpened(Class<?> source, Class<?> target) {287 return true;288 }289 @Override290 boolean canRead(Class<?> source, Class<?> target) {291 return true;292 }293 @Override294 boolean isExported(Class<?> source) {295 return true;296 }297 @Override298 boolean isExported(Class<?> source, Class<?> target) {299 return true;300 }301 @Override302 Class<?> injectionBase(ClassLoader classLoader, String tyoeName) {303 return InjectionBase.class;304 }305 @Override306 void adjustModuleGraph(Class<?> source, Class<?> target, boolean export, boolean read) {307 // empty308 }309 }310}...
Source:SubclassInjectionLoader.java
2import java.lang.reflect.InvocationTargetException;3import java.lang.reflect.Method;4import net.bytebuddy.dynamic.loading.ClassInjector;5import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;6import org.mockito.codegen.InjectionBase;7import org.mockito.exceptions.base.MockitoException;8import org.mockito.internal.util.Platform;9import org.mockito.internal.util.StringUtil;10class SubclassInjectionLoader implements SubclassLoader {11 private static final String ERROR_MESSAGE = StringUtil.join("The current JVM does not support any class injection mechanism.", "", "Currently, Mockito supports injection via neither by method handle lookups or using sun.misc.Unsafe", "Neither seems to be available on your current JVM.");12 private final SubclassLoader loader;13 SubclassInjectionLoader() {14 if (!Boolean.getBoolean("org.mockito.internal.noUnsafeInjection") && ClassInjector.UsingReflection.isAvailable()) {15 this.loader = new WithReflection();16 } else if (ClassInjector.UsingLookup.isAvailable()) {17 this.loader = tryLookup();18 } else {19 throw new MockitoException(StringUtil.join(ERROR_MESSAGE, "", Platform.describe()));20 }21 }22 private static SubclassLoader tryLookup() {23 try {24 Class<?> cls = Class.forName("java.lang.invoke.MethodHandles");25 Object invoke = cls.getMethod("lookup", new Class[0]).invoke((Object) null, new Object[0]);26 Method method = cls.getMethod("privateLookupIn", new Class[]{Class.class, Class.forName("java.lang.invoke.MethodHandles$Lookup")});27 return new WithLookup(invoke, method.invoke((Object) null, new Object[]{InjectionBase.class, invoke}), method);28 } catch (Exception e) {29 throw new MockitoException(StringUtil.join(ERROR_MESSAGE, "", Platform.describe()), e);30 }31 }32 private static class WithReflection implements SubclassLoader {33 public boolean isDisrespectingOpenness() {34 return true;35 }36 private WithReflection() {37 }38 public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> cls, ClassLoader classLoader, boolean z) {39 ClassLoadingStrategy.Default defaultR = ClassLoadingStrategy.Default.INJECTION;40 Class<InjectionBase> cls2 = cls;41 if (!z) {42 cls2 = InjectionBase.class;43 }44 return defaultR.with(cls2.getProtectionDomain());45 }46 }47 private static class WithLookup implements SubclassLoader {48 private final Object codegenLookup;49 private final Object lookup;50 private final Method privateLookupIn;51 public boolean isDisrespectingOpenness() {52 return false;53 }54 WithLookup(Object obj, Object obj2, Method method) {55 this.lookup = obj;56 this.codegenLookup = obj2;57 this.privateLookupIn = method;58 }59 public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> cls, ClassLoader classLoader, boolean z) {60 if (z) {61 try {62 return ClassLoadingStrategy.UsingLookup.of(this.privateLookupIn.invoke((Object) null, new Object[]{cls, this.lookup}));63 } catch (InvocationTargetException e) {64 if (e.getCause() instanceof IllegalAccessException) {65 return ClassLoadingStrategy.Default.WRAPPER.with(cls.getProtectionDomain());66 }67 throw e.getCause();68 } catch (Throwable th) {69 throw new MockitoException(StringUtil.join("The Java module system prevents Mockito from defining a mock class in the same package as " + cls, "", "To overcome this, you must open and export the mocked type to Mockito.", "Remember that you can also do so programmatically if the mocked class is defined by the same module as your test code", th));70 }71 } else if (classLoader == InjectionBase.class.getClassLoader()) {72 return ClassLoadingStrategy.UsingLookup.of(this.codegenLookup);73 } else {74 return ClassLoadingStrategy.Default.WRAPPER.with(cls.getProtectionDomain());75 }76 }77 }78 public boolean isDisrespectingOpenness() {79 return this.loader.isDisrespectingOpenness();80 }81 public ClassLoadingStrategy<ClassLoader> resolveStrategy(Class<?> cls, ClassLoader classLoader, boolean z) {82 return this.loader.resolveStrategy(cls, classLoader, z);83 }84}...
Source:InjectionBase.java
...6/**7 * This class is required to resolve a method handle lookup for the {@code org.mockito.codegen} package what requires a preexisting class for the package.8 * By defining this class, the JVM (starting from Java 9) assures that this package is a part of the Mockito module such that we gain full access rights.9 */10public class InjectionBase {11 private InjectionBase() {12 throw new UnsupportedOperationException();13 }14}...
InjectionBase
Using AI Code Generation
1public class InjectionBase {2 public static InjectionBase createInjectionBase() {3 return new InjectionBase();4 }5}6public class InjectionBase {7 public static InjectionBase createInjectionBase() {8 return new InjectionBase();9 }10}11public class InjectionBase {12 public static InjectionBase createInjectionBase() {13 return new InjectionBase();14 }15}16public class InjectionBase {17 public static InjectionBase createInjectionBase() {18 return new InjectionBase();19 }20}21public class InjectionBase {22 public static InjectionBase createInjectionBase() {23 return new InjectionBase();24 }25}26public class InjectionBase {27 public static InjectionBase createInjectionBase() {28 return new InjectionBase();29 }30}31public class InjectionBase {32 public static InjectionBase createInjectionBase() {33 return new InjectionBase();34 }35}36public class InjectionBase {37 public static InjectionBase createInjectionBase() {38 return new InjectionBase();39 }40}41public class InjectionBase {42 public static InjectionBase createInjectionBase() {43 return new InjectionBase();44 }45}46public class InjectionBase {47 public static InjectionBase createInjectionBase() {48 return new InjectionBase();49 }50}51public class InjectionBase {52 public static InjectionBase createInjectionBase() {
InjectionBase
Using AI Code Generation
1package org.mockito.codegen;2public class InjectionBase {3public static <T> T injectMocks(T testClass) {4return org.mockito.MockitoAnnotations.initMocks(testClass);5}6}7package org.mockito.codegen;8public class InjectionBase {9public static <T> T injectMocks(T testClass) {10return org.mockito.MockitoAnnotations.initMocks(testClass);11}12}13package org.mockito.codegen;14public class InjectionBase {15public static <T> T injectMocks(T testClass) {16return org.mockito.MockitoAnnotations.initMocks(testClass);17}18}19package org.mockito.codegen;20public class InjectionBase {21public static <T> T injectMocks(T testClass) {22return org.mockito.MockitoAnnotations.initMocks(testClass);23}24}25package org.mockito.codegen;26public class InjectionBase {27public static <T> T injectMocks(T testClass) {28return org.mockito.MockitoAnnotations.initMocks(testClass);29}30}31package org.mockito.codegen;32public class InjectionBase {33public static <T> T injectMocks(T testClass) {34return org.mockito.MockitoAnnotations.initMocks(testClass);35}36}37package org.mockito.codegen;38public class InjectionBase {39public static <T> T injectMocks(T testClass) {40return org.mockito.MockitoAnnotations.initMocks(testClass);41}42}43package org.mockito.codegen;44public class InjectionBase {45public static <T> T injectMocks(T testClass) {46return org.mockito.MockitoAnnotations.initMocks(testClass);47}48}49package org.mockito.codegen;50public class InjectionBase {
InjectionBase
Using AI Code Generation
1public class InjectionBase {2 public static void main(String[] args) {3 InjectionBase injectionBase = new InjectionBase();4 injectionBase.methodToBeMocked();5 }6 public void methodToBeMocked() {7 System.out.println("methodToBeMocked");8 }9}10public class InjectionBaseTest {11 private InjectionBase injectionBase;12 public void setUp() {13 MockitoAnnotations.initMocks(this);14 }15 public void testMethodToBeMocked() {16 injectionBase.methodToBeMocked();17 verify(injectionBase).methodToBeMocked();18 }19}20public class InjectionBaseTest {21 private InjectionBase injectionBase;22 public void setUp() {23 MockitoAnnotations.initMocks(this);24 }25 public void testMethodToBeMocked() {26 injectionBase.methodToBeMocked();27 verify(injectionBase).methodToBeMocked();28 }29}30public class InjectionBaseTest {31 private InjectionBase injectionBase;32 public void setUp() {33 MockitoAnnotations.initMocks(this);34 }35 public void testMethodToBeMocked() {36 injectionBase.methodToBeMocked();37 verify(injectionBase).methodToBeMocked();38 }39}40public class InjectionBaseTest {41 private InjectionBase injectionBase;42 public void setUp() {43 MockitoAnnotations.initMocks(this);44 }45 public void testMethodToBeMocked() {46 injectionBase.methodToBeMocked();47 verify(injectionBase).methodToBeMocked();48 }49}50public class InjectionBaseTest {51 private InjectionBase injectionBase;52 public void setUp() {53 MockitoAnnotations.initMocks(this);54 }55 public void testMethodToBeMocked() {
InjectionBase
Using AI Code Generation
1public class InjectionBaseTest {2 private InjectionBase injectionBase;3 public void testMockCreation() {4 assertNotNull(injectionBase);5 }6}7public class InjectionBaseTest {8 private InjectionBase injectionBase;9 public void testMockCreation() {10 assertNotNull(injectionBase);11 }12}13public class InjectionBaseTest {14 private InjectionBase injectionBase;15 public void testMockCreation() {16 assertNotNull(injectionBase);17 }18}19public class InjectionBaseTest {20 private InjectionBase injectionBase;21 public void testMockCreation() {22 assertNotNull(injectionBase);23 }24}25public class InjectionBaseTest {26 private InjectionBase injectionBase;27 public void testMockCreation() {28 assertNotNull(injectionBase);29 }30}31public class InjectionBaseTest {32 private InjectionBase injectionBase;33 public void testMockCreation() {34 assertNotNull(injectionBase);35 }36}37public class InjectionBaseTest {38 private InjectionBase injectionBase;39 public void testMockCreation() {40 assertNotNull(injectionBase);41 }42}43public class InjectionBaseTest {44 private InjectionBase injectionBase;45 public void testMockCreation() {46 assertNotNull(injectionBase);47 }48}
InjectionBase
Using AI Code Generation
1public class InjectionBase {2 public static int add(int a, int b) {3 return a + b;4 }5}6public class InjectionBase {7 public static int add(int a, int b) {8 return a + b;9 }10}11public class InjectionBase {12 public static int add(int a, int b) {13 return a + b;14 }15}16public class InjectionBase {17 public static int add(int a, int b) {18 return a + b;19 }20}21public class InjectionBase {22 public static int add(int a, int b) {23 return a + b;24 }25}26public class InjectionBase {27 public static int add(int a, int b) {28 return a + b;29 }30}31public class InjectionBase {32 public static int add(int a, int b) {33 return a + b;34 }35}
InjectionBase
Using AI Code Generation
1public class InjectionBase {2 public static void injectMocks(Object testClass) {3 Set<MockedType> mockedTypes = new HashSet<>();4 Set<MockedType> spyedTypes = new HashSet<>();5 Set<MockedType> injectedFields = new HashSet<>();6 Set<MockedType> injectedMethods = new HashSet<>();7 Set<MockedType> injectedConstructors = new HashSet<>();8 Set<MockedType> injectedParameters = new HashSet<>();9 Set<MockedType> injectedMethodParameters = new HashSet<>();10 Set<MockedType> injectedConstructorParameters = new HashSet<>();11 Set<MockedType> injectedFieldsAndParameters = new HashSet<>();12 Set<MockedType> injectedMethodsAndParameters = new HashSet<>();13 Set<MockedType> injectedConstructorsAndParameters = new HashSet<>();14 Set<MockedType> injectedFieldsAndMethodParameters = new HashSet<>();15 Set<MockedType> injectedFieldsAndConstructorParameters = new HashSet<>();16 Set<MockedType> injectedMethodsAndConstructorParameters = new HashSet<>();17 Set<MockedType> injectedFieldsAndMethodsAndParameters = new HashSet<>();18 Set<MockedType> injectedFieldsAndConstructorsAndParameters = new HashSet<>();19 Set<MockedType> injectedMethodsAndConstructorsAndParameters = new HashSet<>();20 Set<MockedType> injectedFieldsAndMethodsAndConstructorParameters = new HashSet<>();21 Set<MockedType> injectedFieldsAndMethodsAndConstructorsAndParameters = new HashSet<>();22 Set<MockedType> injectedFieldsAndMethodsAndConstructorsAndParametersAndSpies = new HashSet<>();23 Set<MockedType> injectedFieldsAndMethodsAndConstructorsAndParametersAndSpiesAndStubs = new HashSet<>();24 Set<MockedType> injectedFieldsAndMethodsAndConstructorsAndParametersAndSpiesAndStubsAndDoubles = new HashSet<>();25 Set<MockedType> injectedFieldsAndMethodsAndConstructorsAndParametersAndSpiesAndStubsAndDoublesAndInjectables = new HashSet<>();26 Set<MockedType> injectedFieldsAndMethodsAndConstructorsAndParametersAndSpiesAndStubsAndDoublesAndInjectablesAndMocks = new HashSet<>();
InjectionBase
Using AI Code Generation
1package org.mockito.codegen;2import org.junit.Test;3import org.junit.runner.RunWith;4import org.mockito.InjectMocks;5import org.mockito.Mock;6import org.mockito.Mockito;7import org.mockito.junit.MockitoJUnitRunner;8@RunWith(MockitoJUnitRunner.class)9public class InjectionBaseTest {10 private InjectionBase injectionBase;11 private ClassUnderTest classUnderTest;12 public void testMethodUnderTest() {13 Mockito.doNothing().when(classUnderTest).methodUnderTest();14 injectionBase.methodUnderTest();15 Mockito.verify(classUnderTest).methodUnderTest();16 }17}18package org.mockito.codegen;19import org.junit.Test;20import org.junit.runner.RunWith;21import org.mockito.InjectMocks;22import org.mockito.Mock;23import org.mockito.Mockito;24import org.mockito.junit.MockitoJUnitRunner;25@RunWith(MockitoJUnitRunner.class)26public class InjectionBaseTest {27 private InjectionBase injectionBase;28 private ClassUnderTest classUnderTest;29 public void testMethodUnderTest() {30 Mockito.doNothing().when(classUnderTest).methodUnderTest();31 injectionBase.methodUnderTest();32 Mockito.verify(classUnderTest).methodUnderTest();33 }34}35package org.mockito.codegen;36import org.junit.Test;37import org.junit.runner.RunWith;38import org.mockito.InjectMocks;39import org.mockito.Mock;40import org.mockito.Mockito;41import org.mockito.junit.MockitoJUnitRunner;42@RunWith(MockitoJUnitRunner.class)43public class InjectionBaseTest {44 private InjectionBase injectionBase;45 private ClassUnderTest classUnderTest;46 public void testMethodUnderTest() {47 Mockito.doNothing().when(classUnderTest).methodUnderTest();48 injectionBase.methodUnderTest();49 Mockito.verify(classUnderTest).methodUnderTest();50 }51}
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!!