I saw a lot of examples how to mock a static method in a class.
I want to mock a static property of the class, that's initialized in its definition.
Something like:
class MyClass {
private static log = LogFactory.getLog(this)
}
I want to mock log property, in order that in my test it should be null, and it should not initialize itself.
Make static getter method :
static def getLog() {
return log
}
Use metaClass.staticto mock method:
Myclass.metaClass.static.getLog = {
return "what you need"
}
You are referring to 'log' as a property, but it's actually not. Assuming that MyClass is a Groovy class, then a property is declared without a private or public modifier, like this:
class MyClass {
static log = LogFactory.getLog(this)
}
What you have is a private static variable with an initializer. In this case, no property access methods are generated, and the variable is not considered a property.
Because it's a private variable with an initializer, and you state that you don't want to change the class, you cannot stop the initializer from running. So the best thing to do here is to mock out the getLog() call to return null. A simple but crude approach would be:
LogFactory.metaClass.static.getLog = {
return null
}
but this will kill all log lookup in the whole application. This could be OK for a simple unit test, but a more specific solution is to use Groovy mocks (MockFor and StubFor), which will allow you to mock the getLog call in a specific block of code. You can find out more here
As a matter of interest, why do you not want the log variable initialized?
Related
I am new to jmockit and StrictExpectations. Inside StrictExpectations I have recorded invocation and return value of static method of non-mocked class and the static method is mocked correctly but I don't know why it is happening. I think since the class is not mocked how is its invocation and return value is getting recorded in StrictExpectations.
My code looks similar to below
#Test
public void test() {
new StrictExpectations () {{
DummyClass.someStaticMethod(anyInt);
result = 10;
}};
assertEquals(10, DummyClass.someStaticMetho(3));
}
My question is even though DummyClass is not defined as a mocked class(something like #Mocked DummyClass d) how we are able to record it's invocation and result.
Per the documentation (https://jmockit.github.io/tutorial/Mocking.html#injectable):
"[S]tatic methods and constructors are also excluded from being mocked. After all, a static method is not associated with any instance of the class, while a constructor is only associated with a newly created (and therefore different) instance."
Thus, you don't have to explicitly Mock a class in order to modify a static-method. It appears just by placing the static-method inside the Expectations-block (in the normal way), you have caused JMockit to override the default-implementation (which would be the obvious intent).
Is there a way to change the return value of the property accessor called when running unit tests? Like mocking the result of the property settingsState?
I am learning to create unit tests. What that class makes is to bring stored data into the program, this data is given in a visual form. In my test, I want to define what is going on there because the window won't open there.
// top-level declaration outside class
val settingsState: ApplicationSettingsState
get() = ServiceManager.getService(ApplicationSettingsState::class.java)
settingsState is not a variable. It is a property.
I am not aware of any way to mock global properties (or global functions). The way mocking works is to cleverly create an object that looks a bit like the object to mock from the outside, but behaves differently on the inside. In the absence of an object to mock, there is no way to mock.
That said, on the bytecode level there are no global variables, properties, whatever. They are all wrapped into classes, because the JVM likes it that way. Some clever bytecode manipulation might be able to achieve some effect – but not MockK.
You can mock the property if you have a mocked object. To paraphrase the documentation:
val mock = mockk(Bus())
every { mock getProperty "speed" } returns 33
Yes you can. You want to mock a property that is declared at top-level. Top-level code in a given Kotlin file MyFile.kt is actually compiled to be inside the class MyFileKt. Let's say we have following Kotlin file named MyFile.kt:
package foo
val bar = "some value"
If we compile this file to JVM bytecode and then decompile the result to Java, we get a Java class that looks similar to this:
package foo;
public final class MyFileKt {
private static final String bar = "some value";
public static final String getBar() {
return bar;
}
}
As you can see, our top-level val we defined earlier is actually translated to a static field with associated getter in the class MyFileKt.
TLDR; Getting back to our original problem, all you need to do is statically mock this field:
mockkStatic("foo.MyFileKt") // Fully-qualified name of the generated class
every { bar } returns "some other test value" // Define what our top-level property should return
The same also works for top-level functions, of course.
I have a Kotlin class like this one
import org.slf4j.LoggerFactory.getLogger
object Doer {
val logger = LoggerFactory.getLogger(Doer::class.java)
fun doSomething() : Int {
logger.warn("Doing.")
return 123
}
}
I would like to have a unit test that verifies logger.warn call was made with relevant message. How do I do this in Kotlin?
One of my ideas was to use a getter for logger and stub that with Mockito, but do I need to declare such method explicitly given that Kotlin generates getters automatically? Method getLogger() is not visible in Doer class, but if I declare it explicitly it conflicts with generated one.
Are there better options to test this?
Second question is how to mock the object instance, since it is initialized by language which is out of my control?
I'm fairly new to unit testing. I've recently encountered a problem where I test a method that does one thing only - it calls a method of an object that's part of the class. The class that this object represents has it's own unit tests.
I understand that this method may change in time, and when it does the test should inform me about if the expected result it. But what can I test in such a method?
My code:
public class MyClassToBeTested
{
private CustomType myObject;
private const myParameter = 2;
(...)
public string MyProperty
{
get
{
return myObject.DoYourStuff(myParameter);
}
}
}
This sounds like you need to capture the call to the underlying object and inspect it (or at least verify that the call has been made). I would mock this object and inject a reference to it (Inversion of Control).
By injecting the object you can provide the real object at deploy time, and the mock during testing.
If something is dependent on something else. i.e. method calls another method, then you should mock it, or simulate its behaviour.
I'm using TypeMock Isolater to mock up some objects for some unit tests - attempting to use the AAA api (so the Isolate calls).
I have a straightforward singleton class where you call a static GetInstance(), which then returns an instance of the class. I thought it would be a simple matter of mocking that up, but I'm running into a very frustrating problem ! I can't seem to make GetInstance() return my mocked object correctly with my expected calls set.
I've tried:
using MST projects (using the Accessor classes) to assign a mocked object directly to the instance variable (faking the object using Memers.MustSpecifyReturnValues, and Isolate.WhenCalled using WithExactArguments to set expectations), but for some reason the mocked object always returns null (and no exceptions).
Mocking Singleton.GetInstance() to return the mocked object. This returns a mocked object which needs WhenCalled set, but now the Isolate.WhenCalled calls I make seem to do nothing on the fake object - so all calls throw an unexpected call exception.
I've also tried mocking the actual method call (eg Singleton.GetInstance().Test()), which will work for the call to that method, but all other calls to other methods on the singleton return null rather then throw an exception as I want it to (because this seems to automatically mock up all the objects without Members.MustSpecifyReturnValues).
All I want is to mock a singleton, and any calls I don't explicitly tell it to expect to throw an exception on. I thought it would be simple, but apparently not ! Sad
Has anyone any idea what I'm doing wrong?
Thanks
James
I think the simple solution will be to create a fake instance of the singleton class and use SwapNextInstace before the actual class constructor is called:
[TestMethod]
public void SetBhaciorOnSingleton()
{
var fake = Isolate.Fake.Instance<SingletonClass>();
Isolate.WhenCalled(() => fake.SomeFunction()).WillReturn(10);
// Set additional behavior on singleton class
Isolate.Swap.NextInstance<SingletonClass>().With(fake);
// This is where the class constructor is being called
var result = SingletonClass.GetInstace().SomeFunction();
Assert.AreEqual(10, result );
}
This solution should work with most scenarios unless the singleton class is created before the test.
If you need to set behavior after the class was created just use WhenCalled:
[TestMethod]
public void SetBhaciorOnSingleton()
{
var fake = Isolate.Fake.Instance<SingletonClass>();
Isolate.WhenCalled(() => fake.SomeFunction()).WillReturn(10);
Isolate.WhenCalled(() => SingletonClass.GetInstace()).WillReturn(fake);
var result = SingletonClass.GetInstace().SomeFunction();
Assert.AreEqual(10, result );
}
Disclaimer I work at Typemock.
You don't need to mock Singleton.GetInstance<>(). Using Isolate.Fake.AllInstances<>() instead of Isolate.Fake.Instance<>() you can mock the singleton. Then by setting the behavior on fake singleton behavior applied to all instances.
Take a look on the example:
public class Singleton
{
private Singleton() { }
static readonly Singleton instance = new Singleton();
public static Singleton Instance { get { return instance; } }
public int ReturnZero()
{
return 0;
}
}
[TestMethod]
public void FakeSingleton()
{
// Here we are setting the same behavior on all instances.
// The behavior we set on fake will apply to past instance as well
var fakeSingleton = Isolate.Fake.AllInstances<Singleton>();
Isolate.WhenCalled(() => fakeSingleton.ReturnZero()).WillReturn(10);
// Assert that the behavior works.
Assert.AreEqual(10, Singleton.Instance.ReturnZero());
}
Thanks.
I didn't try NextInstance before because it doesn't work on interfaces which I didn't really want to change.
But, I've tried it and it does work - although I was assuming the order of setting WhenCalled(s) doesn't really matter, but it definately does. If I do the WhenCalled after the Swap for instance, it doesn't work. It needs to go before the Swap. (Doesn't really make sense to me to be honest - it should be the same object).
However, the last example (one of the ways I had tried), doesn't work for me. I fake, set expecation on fake, and then set expectation on Singleton to return faked instance - but now it returns the concrete instance !
Could it have something to do with the way the constructors are called? I remember seeing something about that...
Alternatively I could use the Swap, but, I wanted to be able to setup all this stuff in a TestSetup, and make minor modifications to the expectations in the actual test, but that doesn't look possible. ?
The best solution is to not use singletons (or any other static mutable data). Just create one instance and use dependency injection to pass it to all objects who need it.
http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne
http://www.youtube.com/watch?v=-FRm3VPhseI