JMock+JUnit测试在Eclipse中未触发"not all expectations were satisfied"报错的问题
This is a common inconsistency caused by how JMock's expectation verification is triggered across different test runners and build environments. Let's break down why this happens and how to fix it.
Root Cause
JMock's Mockery class doesn't automatically verify expectations by default in all JUnit setups. Here's what's playing out in your case:
- NetBeans/Jenkins (Ant script): The test runner or build script is likely triggering JMock's automatic verification (perhaps via a test listener or cleanup hook that checks the
Mockerystate when the test finishes). This catches the unmet expectation, hence the "not all expectations were satisfied" error. - Eclipse: The default JUnit runner isn't triggering this automatic verification. Without an explicit call to
assertIsSatisfied(), JMock doesn't check if all expectations were met—so the test incorrectly passes, even though the expectation wasn't fulfilled.
When you add context.assertIsSatisfied() to the end of your test, you're explicitly telling JMock to verify expectations, which is why Eclipse now correctly fails (matching the NetBeans/Jenkins behavior).
Fixes for Consistent Behavior
To ensure your tests behave the same across all environments, choose one of these approaches:
1. Explicitly Verify Expectations in Each Test
Add context.assertIsSatisfied() at the end of every test method that uses JMock. This makes verification explicit and eliminates room for environment-specific behavior.
Example:
public class FailureExample { private static class Example { public void doSomething() {} } private Mockery context = new Mockery(); @Test public void testFailure() { Example mock = context.mock(Example.class); context.checking(new Expectations() {{ oneOf(mock).doSomething(); }}); // Missing call to mock.doSomething() → expectation unmet // Explicit verification to catch the issue context.assertIsSatisfied(); } }
2. Use JMock's JUnit Rule for Automatic Verification
JMock provides a JUnitRule that automatically verifies expectations after each test runs. This ensures consistent behavior across all IDEs and build systems without needing to add explicit verification calls.
First, add the JMock JUnit rule to your test class:
import org.jmock.integration.junit4.JUnitRule; import org.junit.Rule; public class FailureExample { private static class Example { public void doSomething() {} } @Rule public JUnitRule context = new JUnitRule(); @Test public void testFailure() { Example mock = context.mock(Example.class); context.checking(new Expectations() {{ oneOf(mock).doSomething(); }}); // Missing call to mock.doSomething() → expectation unmet // The rule will automatically verify after test execution, triggering the error } }
This rule handles verification automatically after each test method completes, so you don't need to call assertIsSatisfied() manually. It ensures that whether you run the test in Eclipse, NetBeans, or Jenkins, unmet expectations will be caught every time.
Why This Matters
Consistent test behavior is critical for reliable CI/CD pipelines (like Jenkins) and avoiding "works on my machine" issues. By making verification explicit or using JMock's JUnit integration, you eliminate environment-specific discrepancies entirely.
内容的提问来源于stack exchange,提问作者Stephen M -on strike-

