com.roscopeco.moxy.api.MoxyClassMockEngine Maven / Gradle / Ivy
/*
* MoxyClassMockEngine.java -
*
* Copyright 2018 Ross Bamford
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.roscopeco.moxy.api;
/**
* An engine used to create Moxy class mocks.
*
* Note that this is very different to the standard
* mocking performed by {@link MoxyEngine}s. This style of mocking
* uses runtime instrumentation to transform the supplied classes
* directly, instead of, for example, creating proxy classes.
*
* For example, with class mocks, the following is possible:
*
*
* Moxy.classMocks(MyClass.class); // MyClass may or may not be final...
*
* // ... later
*
* MyClass myClass = new MyClass();
*
* // ... myClass is a mock
*
* assertTrue(Moxy.isMock(myClass));
*
* Moxy.when(() -> myClass.someMethod("args")).thenReturn("Mocked!");
*
* assertThat(myClass.someMethod("args")).isEqualTo("Mocked!");
*
*
* This style of mocking allows you to do things that
* cannot be achieved with standard mocks:
*
*
* - Final classes and methods can be mocked.
* - Constructors become mocks, so can be verified.
* - Static methods become mocks.
* - Objects allocated directly inside tested methods (with
new
)
* will be mocks, and so can be verified (assuming you can get the instance).
*
*
* There are, however, some significant caveats to be aware of:
*
*
* - The transformation will affect existing instances of the
* mocked classes, meaning any instances in use within the running
* JVM will also become mocks.
*
* This is mitigated somewhat by the fact that any pre-existing
* instances are automatically set to call real methods, and have
* all their state copied.
* - Interfaces and abstract methods are not supported.
* - This style of mocking requires a Java Agent to be installed in
* the running JVM. Not all JVMs support this, although it should
* work on all those targeted by Moxy.
* - This style of mocking raises significant security and safety
* issues, and should never be used in production. But you're not
* running tests in production code anyway, right?
*
*
* @author Ross Bamford <roscopeco AT gmail DOT com>
* @since 1.0
*/
public interface MoxyClassMockEngine {
/**
* Convert the given classes to mock classes.
*
* when this method returns, all instances of the given classes will
* be converted to mocks, along with all future instances.
*
* @param classes Classes to convert.
* @since 1.0
*/
public void mockClasses(Class>... classes);
/**
* Reset the given classes to their original, non-mock implementation.
*
* @param classes Classes to convert.
*
* @see #mockClasses(Class...)
* @since 1.0
*/
public void resetClasses(Class>... classes);
/**
* Reset the given classes to their original, non-mock implementation.
*
* @see #mockClasses(Class...)
* @see #resetClasses(Class...)
* @since 1.0
*/
public void resetAllClasses();
}