'Why can't mock static method in Spring condition
this is my code.
class ACondition extends SpringBootConditoin {
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
if (Config.isA()) {
return new ConditionOutcome(true, "ok");
} else {
return new ConditionOutcome(false, "error");
}
}
}
class BCondition extends SpringBootConditoin {
public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
if (Config.isA()) {
return new ConditionOutcome(false, "error");
} else {
return new ConditionOutcome(true, "ok");
}
}
}
@Service
@Conditional(ACondition.class)
class APolicy implements Policy {
...
}
@Service
@Conditional(BCondition.class)
class BPolicy implements Policy {
...
}
class PolicyManager {
@Autowired
@Getter
List<Policy> policyList;
...
}
the default value of Config.isA() is true. I want to make Config.isA() to return false. so I use Mockito.mockstatic.
@Autowired
PolicyManager manager;
@Test
public void get_B_policy() {
try(MockedStatic<Config> mocked = Mockito.mockStatic(Config.class) {
mocked.when(() -> Config.isA()).thenReturn(false);
List<Policy> policyList = manager.getPolicyList();
assertEquals(1, policyList.size()); // this is right
assertTrue(policyList.get(0) instanceof BPolicy); // this is not right
}
}
Why can't mock the online method?
by the way. If I test the BCondition class, the Config.isA() can be mocked. I can enter the branch which I want. It does not work only in conditional annotation.
Solution 1:[1]
Spring Context is already loaded by the time it is reaching the Test Case. Hence, Manager already has selected APolicy
.
If you could move the static mock config before spring context loads, then it should match your expectations.
mocked.when(() -> Config.isA()).thenReturn(false);
One way of doing it is initialising the static Mock like below -
Junit4
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {PolicyManager.class, APolicy.class, BPolicy.class})
public class ConditionTest
{
@Autowired
PolicyManager manager;
static MockedStatic<Config> mocked = Mockito.mockStatic(Config.class);
@BeforeClass
public static void setup()
{
mocked.when(() -> Config.isA()).thenReturn(false);
}
@AfterClass
public static void clear()
{
mocked.close();
}
@Test
public void get_B_policy() {
List<Policy> policyList = manager.getPolicyList();
assertEquals(1, policyList.size()); // this is right
assertTrue(policyList.get(0) instanceof BPolicy); // should work now
}
}
Junit5 Please use Jupiter's annotations.
@Autowired
PolicyManager manager;
static MockedStatic<Config> mocked = Mockito.mockStatic(Config.class);
@BeforeAll
public static void setup() {
mocked.when(() -> Config.isA()).thenReturn(true);
}
@AfterAll
public static void clear() {
mocked.close();
}
@Test
public void get_B_policy() {
List<Policy> policyList = manager.getPolicyList();
assertEquals(1, policyList.size()); // this is right
assertTrue(policyList.get(0) instanceof BPolicy); // should work now
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |