Git Product home page Git Product logo

mockito-testng's Introduction

Mockito

Most popular mocking framework for Java

CI Coverage Status MIT License

Release Notes Maven Central Javadoc

Current version is 5.x

Still on Mockito 1.x? See what's new in Mockito 2! Mockito 3 does not introduce any breaking API changes, but now requires Java 8 over Java 6 for Mockito 2. Mockito 4 removes deprecated API. Mockito 5 switches the default mockmaker to mockito-inline, and now requires Java 11. Only one major version is supported at a time, and changes are not backported to older versions.

Mockito for enterprise

Available as part of the Tidelift Subscription.

The maintainers of org.mockito:mockito-core and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more.

Development

Mockito publishes every change as a -SNAPSHOT version to a public Sonatype repository. Roughly once a month, we publish a new minor or patch version to Maven Central. For release automation we use Shipkit library (http://shipkit.org), Gradle Nexus Publish Plugin. Fully automated releases are awesome, and you should do that for your libraries, too! See the latest release notes and latest documentation. Docs in javadoc.io are available 24h after release. Read also about semantic versioning in Mockito.

Older 1.x and 2.x releases are available in Central Repository and javadoc.io (documentation).

More information

All you want to know about Mockito is hosted at The Mockito Site which is Open Source and likes pull requests, too.

Want to contribute? Take a look at the Contributing Guide.

Enjoy Mockito!

Need help?

How to develop Mockito?

To build locally:

 ./gradlew build

To develop in IntelliJ IDEA you can use built-in Gradle import wizard in IDEA. Alternatively generate the importable IDEA metadata files using:

 ./gradlew idea

Then, open the generated *.ipr file in IDEA.

How to release new version?

  1. Every change on the main development branch is released as -SNAPSHOT version to Sonatype snapshot repo at https://s01.oss.sonatype.org/content/repositories/snapshots/org/mockito/mockito-core.
  2. In order to release a non-snapshot version to Maven Central push an annotated tag, for example:
git tag -a -m "Release 3.4.5" v3.4.5
git push origin v3.4.5
  1. At the moment, you may not create releases from GitHub Web UI. Doing so will make the CI build fail because the CI creates the changelog and posts to GitHub releases. We'll support this in the future.

mockito-testng's People

Contributors

dependabot[bot] avatar mockitoguy avatar mouyang avatar shestee avatar shipkit-org avatar slawekjaranowski avatar timvdlippe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

mockito-testng's Issues

UnfinishedMockingSessionException when using MockitoTestNGListener instead of openMocks

Hi,

I'm using the @Listeners(MockitoTestNGListener.class) (mockito-testng 0.2.10) in a project to avoid all those open/close mocks.

While is it is running fine with some of use cases, I found a strange behavior:
Here a simple test class:

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.mockito.Mockito.when;

import java.util.Map;

import org.assertj.core.data.MapEntry;
import org.mockito.Mock;
import org.mockito.testng.MockitoTestNGListener;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

@Listeners(MockitoTestNGListener.class)
public class MockitoTestNgListenerTest1 {

    @Mock
    private Map<String, Object> map;

    private MapEntry<String, String> entry;

    @SuppressWarnings("rawtypes")
    @BeforeTest
    public void setUp() {
        entry = entry("Boo", "Minsc");
        when(map.get(0)).thenReturn(entry);
    }

    @Test
    public void shouldWork() {
        assertThat(map.get(0)).isEqualTo(entry);
    }
}

No big deal. It runs ok with TestNG.

Now duplicate this class and rename it. Now launch the 2 classes and the exception is thrown. All unit tests fail.

org.mockito.exceptions.misusing.UnfinishedMockingSessionException: 
Unfinished mocking session detected.
Previous MockitoSession was not concluded with 'finishMocking()'.
For examples of correct usage see javadoc for MockitoSession class.

	at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1133)
	at org.testng.internal.invokers.InvokedMethodListenerInvoker.invokeListener(InvokedMethodListenerInvoker.java:56)
	at org.testng.internal.BaseInvoker.runInvokedMethodListeners(BaseInvoker.java:55)
	at org.testng.internal.ConfigInvoker.invokeConfigurationMethod(ConfigInvoker.java:351)
	at org.testng.internal.ConfigInvoker.invokeConfigurations(ConfigInvoker.java:320)
	at org.testng.TestRunner.invokeTestConfigurations(TestRunner.java:617)
	at org.testng.TestRunner.beforeRun(TestRunner.java:607)
	at org.testng.TestRunner.run(TestRunner.java:578)
	at org.testng.SuiteRunner.runTest(SuiteRunner.java:384)
	at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:378)
	at org.testng.SuiteRunner.privateRun(SuiteRunner.java:337)
	at org.testng.SuiteRunner.run(SuiteRunner.java:286)
	at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
	at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
	at org.testng.TestNG.runSuitesSequentially(TestNG.java:1218)
	at org.testng.TestNG.runSuitesLocally(TestNG.java:1140)
	at org.testng.TestNG.runSuites(TestNG.java:1069)
	at org.testng.TestNG.run(TestNG.java:1037)
	at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:73)
	at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)

Note that those simple tests run fine with open/close mocks (or if the BeforeTest is changed to BeforeMethod).

Thanks.
------- Maven dependencies used:
JDK 11.0.6 / 11.0.8
Mockito-testng 0.2.10
TestNG version 7.3.0
Mockito 3.7.7

Timeout during release job on GitHub Action

Release job hangs on bintrayPublish
During standard run no more useful logs are produced

2020-12-09T11:15:57.2854953Z > Task :bintrayPublish
2020-12-09T12:26:44.3516989Z ##[error]The operation was canceled.

Artifacts are deployed to bintray, but not synced to Maven Central.

So I suspect, that sync take too much time and during wait for status no output is produced what can be cause to kill some thread or process by github.

MockitoTestNGListener retains mocks between test methods

MockitoTestNGListener re-uses MockitoSessions between test methods. Instead of giving each test method its own independent mocks, it calls 'reset' on the mocks between test methods.

The effect of this is that mock instances are the same for multiple test methods, which can lead to confusing behavior, for example if the mock object was passed to a separate thread in one test, that separate thread can continue to make calls to the mock during later tests, causing spurious results.

@InjectMock and class with final fields

example:

@Listeners(MockitoTestNGListener.class)
public class InjectMocksWithConstructorAndFinalTest {

    interface Client {}

    static class Service {
        final Client client;

        public Service(Client client) {
            this.client = client;
        }
    }

    @Mock
    private Client client;

    @InjectMocks
    private Service service;

    @AfterMethod
    void cleanup() {
        service = null;
    }
   
  @Test(invocationCount = 4)
    void inject_mock_should_be_refreshed() {
      ....
    }
}

For each test method new @Mocks are created but service is initialized only once at the beginning.
And @InjectMocks cannot insert into final field, so we must clear service in @AfterMethod

In other case we will have in service reference to old mock client object.

mockito/mockito#1437

Make strict stubs the default setting for TestNGListener

Mockito is converging on using strict stubbing mechanism so let's configure TestNGListener to also use strict stubs by default.

Strict stubbing in Mockito:

  • default for JUnit5 Mockito
  • default for MockitoSession API
  • planned as default for Mockito 3 for JUnit 4 rules + runners

Since TestNG integration is not announced yet, and it has 0.* version, it is ok to update the defaults now.

Thoughts/feedback?

Configure Strictness

My reason for doing this is outlined in this issue comment. It's available in JUnitRule but not MockitoTestNGListener. At a minimum, strictness should be configurable as a suite parameter. Overriding the strictness at a lower level is out of scope.

Set in testng.xml

<?xml version="1.0" encoding="UTF-8"?>
<suite name="strictness">
  <parameter name="org.mockito.testng.strictness"  value="LENIENT"/>
  <!-- etc. -->
</suite>

Set in annotation

@BeforeSuite // or any TestNG annotation for that matter
public void beforeSuite(ITestContext iTestContext) {
  iTestContext.getSuite().getXmlSuite().setParameter("org.mockito.testng.strictness", Strictness.LENIENT);
}

MockitoTestNGListener does not close session on exception in before method

The MockitoTestNGListener does not close the session of before methods in case an exception is thrown in the before method. All follow-up tests will fail. This is a problem especially in test pipelines when you run 100s of tests. Finding the cause takes longer than necessary. In these scenarios it also appears that getting the class name from ITestResult returns null. This causes an NPE when calling hasMockitoTestNGListener.

I would propose the following solutions in the listener:

protected boolean hasMockitoTestNGListener(ITestResult testResult) {
		return nonNull(testResult.getTestClass())
				&& findAnnotation(testResult, Listeners.class)
				.map(Listeners::value)
				.map(Arrays::stream)
				.orElseGet(Stream::empty)
				.anyMatch(listener -> listener == MockitoTestNGListener.class);
}

Important part is to return true in shouldBeRunAfterInvocation in case an exception was thrown in the before method.

private boolean shouldBeRunAfterInvocation(IInvokedMethod method, ITestResult testResult) {
	return (method.isTestMethod() && hasMockitoTestNGListener(testResult))
		|| (isBeforeMethod(method) && nonNull(testResult.getThrowable()));
}

Hope this makes sense. I actually ran into the situation and applying these changes fixed it for me. With the fix I only see the tests from the same test class failing and not other tests afterwards as well.

Release mockito-testng to Maven Central

I've just tried it and got:

Last Sync Errors: Invalid POM: /org/mockito/mockito-testng/0.1.0/mockito-testng-0.1.0.pom: Developer information missing, Invalid version for Dependency {groupId=org.mockito, artifactId=mockito-core, version=2.+, type=jar} - uses invalid dynamic version syntax. Replace with a fixed version or standard mathematical notation e.g., [1.5,) for version 1.5 and higher. Dropping existing partial staging repository.

Test run in multiple threads

We can annotate test with:

    @Mock
    private MyType mock;

    @Test(threadPoolSize = 3, invocationCount = 8)
    public void testParallel() {
     ....
    }

In this case MockitoTestNGListener will not work as we want.
In current implementation MockitoSession is bind to current test instance, but TestNG create one test instance and run test in multiple thread.

Issue need more investigate how to resolve problem.

We must to check and discover how mocked field should be distinguished on one test instance and multiple thread.

Please like / react on issue to we see how many people are interested this issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.