2525import com .optimizely .ab .android .odp .ODPEventClient ;
2626import com .optimizely .ab .android .odp .ODPSegmentClient ;
2727import com .optimizely .ab .android .odp .VuidManager ;
28- import com .optimizely .ab .android .sdk .cmab .CMABClient ;
28+ import com .optimizely .ab .android .sdk .cmab .DefaultCmabClient ;
2929import com .optimizely .ab .android .shared .Client ;
3030import com .optimizely .ab .android .shared .DatafileConfig ;
3131import com .optimizely .ab .android .user_profile .DefaultUserProfileService ;
3232import com .optimizely .ab .bucketing .UserProfileService ;
33+ import com .optimizely .ab .cmab .client .CmabClient ;
34+ import com .optimizely .ab .cmab .service .DefaultCmabService ;
3335import com .optimizely .ab .error .ErrorHandler ;
3436import com .optimizely .ab .event .BatchEventProcessor ;
3537import com .optimizely .ab .event .EventHandler ;
3638import com .optimizely .ab .event .EventProcessor ;
39+ import com .optimizely .ab .internal .DefaultLRUCache ;
3740import com .optimizely .ab .notification .NotificationCenter ;
3841import com .optimizely .ab .odp .ODPEventManager ;
3942import com .optimizely .ab .odp .ODPManager ;
5558import static org .junit .Assert .assertFalse ;
5659import static org .junit .Assert .assertNotNull ;
5760import static org .junit .Assert .assertNull ;
61+ import static org .mockito .ArgumentMatchers .anyInt ;
5862import static org .mockito .ArgumentMatchers .anyLong ;
5963import static org .mockito .ArgumentMatchers .anyString ;
6064import static org .mockito .ArgumentMatchers .isNull ;
7579import java .util .concurrent .TimeUnit ;
7680
7781@ RunWith (PowerMockRunner .class )
78- @ PrepareForTest ({OptimizelyManager .class , BatchEventProcessor .class , DefaultEventHandler .class , ODPManager .class , ODPSegmentManager .class , ODPEventManager .class , VuidManager .class })
82+ @ PrepareForTest ({
83+ OptimizelyManager .class ,
84+ BatchEventProcessor .class ,
85+ DefaultEventHandler .class ,
86+ ODPManager .class ,
87+ ODPSegmentManager .class ,
88+ ODPEventManager .class ,
89+ VuidManager .class ,
90+ CmabClient .class ,
91+ DefaultCmabService .class
92+ })
7993public class OptimizelyManagerBuilderTest {
8094
8195 private String testProjectId = "7595190003" ;
@@ -261,6 +275,7 @@ public void testBuildWithDefaultODP_defaultEnabled() throws Exception {
261275 any (NotificationCenter .class ),
262276 any (), // nullable (DefaultDecideOptions)
263277 any (ODPManager .class ),
278+ any (),
264279 eq ("test-vuid" ),
265280 any (),
266281 any ());
@@ -291,6 +306,7 @@ public void testBuildWithDefaultODP_disabled() throws Exception {
291306 any (NotificationCenter .class ),
292307 any (), // nullable (DefaultDecideOptions)
293308 isNull (),
309+ any (),
294310 eq ("test-vuid" ),
295311 any (),
296312 any ());
@@ -468,30 +484,29 @@ public void testBuildWithVuidEnabled() throws Exception {
468484 when (ODPManager .builder ()).thenCallRealMethod ();
469485 }
470486
487+ DefaultCmabService .Builder getMockDefaultCmabServiceBuilder () {
488+ DefaultCmabService .Builder mockBuilder = PowerMockito .mock (DefaultCmabService .Builder .class );
489+ when (mockBuilder .withClient (any ())).thenReturn (mockBuilder );
490+ when (mockBuilder .withCmabCacheSize (anyInt ())).thenReturn (mockBuilder );
491+ when (mockBuilder .withCmabCacheTimeoutInSecs (anyInt ())).thenReturn (mockBuilder );
492+ return mockBuilder ;
493+ }
494+
471495 @ Test
472496 public void testCmabServiceConfigurationValidation () throws Exception {
473497 // Custom configuration values
474498 int customCacheSize = 500 ;
475499 int customTimeoutMinutes = 45 ;
476500 int expectedTimeoutSeconds = customTimeoutMinutes * 60 ; // 45 min = 2700 sec
477- CMABClient mockCmabClient = mock (CMABClient .class );
478-
479- // Create mocks for the CMAB service creation chain
480- Object mockDefaultLRUCache = PowerMockito .mock (Class .forName ("com.optimizely.ab.cache.DefaultLRUCache" ));
481- Object mockCmabServiceOptions = PowerMockito .mock (Class .forName ("com.optimizely.ab.cmab.CmabServiceOptions" ));
482- Object mockDefaultCmabService = PowerMockito .mock (Class .forName ("com.optimizely.ab.cmab.DefaultCmabService" ));
501+ CmabClient mockCmabClient = mock (CmabClient .class );
483502
484- // Mock the construction chain with parameter validation
485- whenNew ( Class . forName ( "com.optimizely.ab.cache.DefaultLRUCache" ))
486- . thenReturn (mockDefaultLRUCache );
503+ DefaultCmabService . Builder mockBuilder = getMockDefaultCmabServiceBuilder ();
504+ mockStatic ( DefaultCmabService . class );
505+ when ( DefaultCmabService . builder ()). thenReturn (mockBuilder );
487506
488- whenNew ( Class . forName ( "com.optimizely.ab.cmab.CmabServiceOptions" ))
489- . thenReturn (mockCmabServiceOptions );
507+ DefaultCmabService mockDefaultCmabService = mock ( DefaultCmabService . class );
508+ when ( mockBuilder . build ()). thenReturn (mockDefaultCmabService );
490509
491- whenNew (Class .forName ("com.optimizely.ab.cmab.DefaultCmabService" ))
492- .thenReturn (mockDefaultCmabService );
493-
494- // Use PowerMock to verify OptimizelyManager constructor is called with CMAB service
495510 whenNew (OptimizelyManager .class ).withAnyArguments ().thenReturn (mock (OptimizelyManager .class ));
496511
497512 OptimizelyManager manager = OptimizelyManager .builder (testProjectId )
@@ -500,14 +515,10 @@ public void testCmabServiceConfigurationValidation() throws Exception {
500515 .withCmabClient (mockCmabClient )
501516 .build (mockContext );
502517
503- verifyNew (Class .forName ("com.optimizely.ab.cache.DefaultLRUCache" ))
504- .withArguments (eq (customCacheSize ), eq (expectedTimeoutSeconds ));
505-
506- verifyNew (Class .forName ("com.optimizely.ab.cmab.CmabServiceOptions" ))
507- .withArguments (any (), eq (mockDefaultLRUCache ), eq (mockCmabClient ));
508-
509- verifyNew (Class .forName ("com.optimizely.ab.cmab.DefaultCmabService" ))
510- .withArguments (eq (mockCmabServiceOptions ));
518+ verify (mockBuilder ).withCmabCacheSize (eq (customCacheSize ));
519+ verify (mockBuilder ).withCmabCacheTimeoutInSecs (eq (expectedTimeoutSeconds ));
520+ verify (mockBuilder ).withClient (eq (mockCmabClient ));
521+ verify (mockBuilder ).build ();
511522
512523 // Verify OptimizelyManager constructor was called with the mocked CMAB service
513524 verifyNew (OptimizelyManager .class ).withArguments (
@@ -540,24 +551,12 @@ public void testCmabServiceDefaultConfigurationValidation() throws Exception {
540551 int defaultCacheSize = 100 ;
541552 int defaultTimeoutSeconds = 30 * 60 ; // 30 minutes = 1800 seconds
542553
543- // Create mocks for the CMAB service creation chain
544- Object mockDefaultLRUCache = PowerMockito .mock (Class .forName ("com.optimizely.ab.cache.DefaultLRUCache" ));
545- Object mockDefaultCmabClient = PowerMockito .mock (Class .forName ("com.optimizely.ab.cmab.DefaultCmabClient" ));
546- Object mockCmabServiceOptions = PowerMockito .mock (Class .forName ("com.optimizely.ab.cmab.CmabServiceOptions" ));
547- Object mockDefaultCmabService = PowerMockito .mock (Class .forName ("com.optimizely.ab.cmab.DefaultCmabService" ));
548-
549- // Mock the construction chain with parameter validation
550- whenNew (Class .forName ("com.optimizely.ab.cache.DefaultLRUCache" ))
551- .thenReturn (mockDefaultLRUCache );
552-
553- whenNew (Class .forName ("com.optimizely.ab.cmab.DefaultCmabClient" ))
554- .thenReturn (mockDefaultCmabClient );
554+ DefaultCmabService .Builder mockBuilder = getMockDefaultCmabServiceBuilder ();
555+ mockStatic (DefaultCmabService .class );
556+ when (DefaultCmabService .builder ()).thenReturn (mockBuilder );
555557
556- whenNew (Class .forName ("com.optimizely.ab.cmab.CmabServiceOptions" ))
557- .thenReturn (mockCmabServiceOptions );
558-
559- whenNew (Class .forName ("com.optimizely.ab.cmab.DefaultCmabService" ))
560- .thenReturn (mockDefaultCmabService );
558+ DefaultCmabService mockDefaultCmabService = mock (DefaultCmabService .class );
559+ when (mockBuilder .build ()).thenReturn (mockDefaultCmabService );
561560
562561 // Use PowerMock to verify OptimizelyManager constructor is called with CMAB service
563562 whenNew (OptimizelyManager .class ).withAnyArguments ().thenReturn (mock (OptimizelyManager .class ));
@@ -566,19 +565,10 @@ public void testCmabServiceDefaultConfigurationValidation() throws Exception {
566565 OptimizelyManager manager = OptimizelyManager .builder (testProjectId )
567566 .build (mockContext );
568567
569- verifyNew (Class .forName ("com.optimizely.ab.cache.DefaultLRUCache" ))
570- .withArguments (eq (defaultCacheSize ), eq (defaultTimeoutSeconds ));
571-
572- // Verify DefaultCmabClient is created with default parameters
573- verifyNew (Class .forName ("com.optimizely.ab.cmab.DefaultCmabClient" ))
574- .withNoArguments ();
575-
576- // Verify CmabServiceOptions is created with logger, cache, and default client
577- verifyNew (Class .forName ("com.optimizely.ab.cmab.CmabServiceOptions" ))
578- .withArguments (any (), eq (mockDefaultLRUCache ), eq (mockDefaultCmabClient ));
579-
580- verifyNew (Class .forName ("com.optimizely.ab.cmab.DefaultCmabService" ))
581- .withArguments (eq (mockCmabServiceOptions ));
568+ verify (mockBuilder ).withCmabCacheSize (eq (defaultCacheSize ));
569+ verify (mockBuilder ).withCmabCacheTimeoutInSecs (eq (defaultTimeoutSeconds ));
570+ verify (mockBuilder ).withClient (any (DefaultCmabClient .class ));
571+ verify (mockBuilder ).build ();
582572
583573 // Verify OptimizelyManager constructor was called with the mocked CMAB service
584574 verifyNew (OptimizelyManager .class ).withArguments (
0 commit comments