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).
Related
I have a two classes let's say classA and classB. classA calls a method in classB which saves some value in a database using the DaoClass.
I have to test if the values are getting saved in database.
#Mocks
private DaoClass dao;
#Mocks
private ClassB B;
#InjectMocks
private ClassA A;
A.someMethod(someArgument);
verify(B).someOtherMethod(someOtherArgument);
verify(dao).save(theCorrectValue);
This fails saying there were zero interactions with this mock. Wanted but not invoked dao.save(). Whereas B.someOtherMethod() was invoked.
I am new to development and testing and my understanding was that I just have to mock call a method in my first class and then that call would proceed like a normal call and all the methods in all the other classes would be called normally. But it seems that it only calls a method in classB and then does not do anything in classB. For example, I debugged by creating breakpoints all over ClassB:
ClassB someOtherMethod{
SomeCode;
SomeCode;
dao.save();
someCode;
return Something; }
In debugger I can see it goes to ClassB someOtherMethod() but after that it skips all the code and goes to return statement. Am I missing something? Do I need to go through some documents?
You would have to either
stub the ClassB someOtherMethod. Note that if you don't specify the return value of any of the mocked dependencies (with when()) it will return the default value for the return type - null for objects, 0 for primitive numbers, false for boolean, etc. This is why you must be getting Null when someOtherMethod is called.
Use Spy instead of Mock. if you want to call external service and perform calling of real dependency, or simply say, you want to run the program as it is and just stub specific methods, then use spy.
I am writing unit tests for a class that has a method that calls other methods of the same class. This is leading to a lot of scenarios to be tested.
I am of the opinion that I can spy() the behaviour of the method calls so that I am testing only the method under test and not bothered about other methods behaviour. I will cover them through a separate test for each of those methods.
class MyClass{
public void myMethodToBeTested(){
aPrivateMethod();
aPublicMethod();
}
private void aPrivateMethod(){
// doing something
// Has some if else scenarios
}
public void aPublicMethod(){
// doing something
// Has some if else scenarios
}
}
What would be best way to unit test this class?
You should test by calling the external interface of the class i.e. the public methods.
If those methods call private methods in the same class, then those private methods need to be fully covered too - otherwise how would they be tested?
Stubbing or spying only makes sense for calls to resources or classes outside the class under test.
You're trying to test the entire class, not just individual methods.
In my view the aPrivateMethod could go to a separate class as public and also the body of the aPublicMethod could be a different method in that class.
After this refactoring you can inject the new class and call those methods in the corresponding places.
When it comes to testing, you could mock/stub those methods and test the myMethodToBeTested().
First off, I'd change the private method to default / package-level. That way, a unit test occupying the same package can access it but other methods, outside of that package, can't touch it. Not quite the same thing as private scope, but close enough most of the time.
Then, setup a Spy() on MyClass.
In case you're not clear on that term:
A Mock() on a class will always return null or 0 to any method call
A Stub() on a class lets you define what certain methods in that class should do, but anything you DON'T explicitly specify always returns a null or 0
A Spy() lets you create an object of a class, with all methods in place EXCEPT you can override some of those methods
So create a Spy(MyClass), specify what aPrivateMethod() and aPublicMethod() should return for testing purposes then call myMethodToBeTested() and see what is returned. In your example, that method is void, so it doesn't return anything. But you can always:
define a variable outside of the Spy()
have aPublicMethod() set / modify the variable based on inputs or internal state (your overriding methods in your Spy() can take parameters)
call myMethodToBeTested()
check the contents of that variable
I want to test if a method has been called in the test.
My problem is that when I want to create the expectations it is not working as I thought. The next line actually runs the method, not only create an expectation:
Expect.Call(() => mockedService.MethodThatIExpectToRun(params));
There is another way:
mockedService.Expect((s=> s.MethodThatIExpectToRun(params)));
But this also actually runs the method, not only creates an expectation to be fulfilled by the test.
And this line that asserts if the method was not called also actually calls the method, not only checks whether it was called.
mockedService.AssertWasCalled(s=> s.MethodThatIExpectToRun((params)));
additional info:
MethodThatIExpectToRun returns void
For prgmtc's comment:
IService mockedService = MockRepository.GeneratePartialMock<Service>(mockedRepository_1, ..., mockedRepository_n);
Usually when you have PartialMock that's calling the real method when setting a Stub or Expect, it means the virtual keyword is missing on the method.
Make sure Service.MethodThatIExpectToRun is virtual.
A more general (although perhaps less useful) remark: Partial mocks can point to a design smell of the code under test. If you only want to provide expectations for a part of a class, then perhaps that class has too many responsibilities and should be split into multiple classes? That way you can cleanly isolate responsibilities/collaborators and have no need for the partialmock construct. If you mock (not partial mock) an interface or virtual member of a concrete class the call won't go through to the real implementation.
For example:
Console.WriteLine("Real object: ");
new Foo().Bar();
Console.WriteLine("Mocked object: ");
var aFoo = MockRepository.GenerateMock<Foo>();
aFoo.Expect(f => f.Bar());
aFoo.Bar();
...
public class Foo
{
public virtual void Bar()
{
Console.WriteLine("REAL IMPLEMENTATION");
}
}
Outputs:
Real object:
REAL IMPLEMENTATION
Mocked object:
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