I am trying to augment existing Java project with some Groovy goodness, starting with tests.
So, let's say I have ServiceA (Java class) that depends on ServiceB (another Java class); it is passed as a reference in constructor:
public class ServiceA {
private ServiceB serviceB;
public ServiceA(ServiceB seviceB){
this.serviceB = serviceB;
}
public boolean doSomeWork(){
//some logic
return serviceB.doMoreWork();
}
}
Let's assume that serviceB.doMoreWork() returns true.
In order to test ServiceA I want to mock ServiceB using MockFor:
#Test
void testDoSomeWork(){
def mocker = new MockFor(ServiceB) //1 create the Mock support
mocker.demand.doMoreWork(2){ //2 twice for this demonstration
false //3 return other value than in real code
}
mocker.use {
def mockServiceB = new ServiceB() //4 creates mock instead of real one
assert !mockServiceB.doMoreWork() //5 that's good!
def serviceA = new ServiceA(mockServiceB)
assert !serviceA.doSomeWork() //6 that fails! Real implementation called!
}
}
As you can see, the same object acts as mock in #5 and as real object in #6. I assume it has something to do with the fact that it is Java Object, not GoovyObject. What gives?
Thanks!
Baruch.
1) The following understanding is wrong:
def mockServiceB = new ServiceB() //4 creates mock instead of real one
You are not creating mock here. You are creating the real object. It's the method dispatch that Groovy routes differently.
2) In the code below, Groovy takes care of routing your doMoreWork() call to mock version because "new MockFor(ServiceB).demand.doMoreWork" gives Groovy the information that there is a stubbed implementation of doMoreWork()
def mocker = new MockFor(ServiceB)
mocker.use {
mockServiceB.doMoreWork()
}
So, the above magic works when mockServiceB.doMoreWork() call is made from Groovy.
When the same call is made from Java, it does not go through Groovy's MOP infrastructure, so it goes directly to the real implementation of doMoreWork()
Remember: for MockFor, Groovy does not do any bytecode instrumentation, etc so that the modified class is visible in Java as well.
Related
I have some (Scala) code in Play which uses JPA for DB access. Works fine. But I want to unit test my code, which will require using a mock EntityManager. Is this possible?
My test is written in specs2 (by extending PlaySpecification) and is run with JUnit. I am using Mockito to mock the EntityManager. But I would expect to be able to do this with other frameworks.
Here's what my code looks like:
object MyThing {
def create(...) : MyThing = {
val newThing = ...
JPA.withTransaction(new play.libs.F.Function0[Unit]() {
def apply() = {
JPA.em().persist(newThing)
}
})
return newThing
}
}
If it is not possible to unit test this code, is there some alternate approach to data access which is recommended?
Apparently there is no way to use a mock EntityManager here, at least none that I could find. So I had to revise my design.
Will Sargent of Typesafe suggested creating a separate DB persistence subproject on the mailing list: https://groups.google.com/d/msg/play-framework/1u-_JbTIuQg/L5_9o4YCfoMJ. I haven't gone quite that far, but I did find a solution that worked for me by defining a separate DAO interface.
I put all the JPA code into a DAO trait - all the implementation is in there. There's also a companion object to provide a singleton instance. Like so:
trait MyThingDAO {
def create(...) : MyThing = { ... }
}
object MyThingDAO extends MyThingDAO
Now I change my controllers to traits, with a reference to the DAO left unset. A companion object sets the DAO instance to the singleton object. This avoids making any changes to the routes file (no need to instantiate the controllers). Like so:
trait MyThingController {
val myThingDao : MyThingDAO
def myAction = Action { implicit request => ... }
}
object MyThingController {
val myThingDao = MyThingDAO
}
So everything works easily enough with the standard JPA code when the app is running. But when I want to unit test, I can insert a mock DAO like so (this is using Mockito):
...
val mockDao = mock[MyThingDAO]
val controller = new MyThingController() { val myThingDao = mockDao }
...
Maybe this isn't the ideal approach, but it has been working so far. I would still be interested to hear any other suggestions.
Say I've got a controller with an action that receives two parameters.
It invokes two services, one with each parameter, the services both return strings
each of those strings are passed as arguments to a template
the result is passed to Ok and returned.
I want to write a simple unit test that ensures:
1 - The correct services are invoked with the correct parameters
2 - The return values from the services are passed to the correct attributes of the template
What is the best way to do that?
Using Mockito with Specs2, I mock services to verify their method calls.
My controller is instantiated by Spring. That allows me to treat it is as a class instead of object. => That is essential to make controller testable. Here an example:
#Controller
class MyController #Autowired()(val myServices: MyServices) extends Controller
To enable Spring for controllers, you have to define a Global object, as the Play! documentation explains:
object Global extends GlobalSettings {
val context = new ClassPathXmlApplicationContext("application-context.xml")
override def getControllerInstance[A](controllerClass: Class[A]): A = {
context.getBean(controllerClass)
}
}
My unit test doesn't need Spring; I just pass collaborators (mocks) to constructor.
However, concerning the rendered template, I test only for the type of result (Ok, BadRequest, Redirection etc...).
Indeed, I noticed it's not easy at all to make my test scan the whole rendered template in details (parameters sent to it etc..), with only unit testing.
Thus, in order to assert that the right template is called with the right arguments, I trust my acceptance tests running Selenium, or a possible functional test, if you prefer, to scan for the whole expected result.
2 - The return values from the services are passed to the correct
attributes of the template
It's pretty easy to check for that..How? By trusting compiler! Prefer to pass some custom types to your template instead of simple primitives for instance:
phone: String would become: phone: Phone. (a simple value object).
Therefore, no fear to pass the attributes in a non-expected order to your template (in unit test or real production code). Compiler indeed will warn.
Here's an example of one of my unit test (simplified) using specs2:
(You will note the use of a wrapper: WithFreshMocks).
This case class would allow to refresh all variables (mocks in this case) test after test.
Thus a good way to reset mocks.
class MyControllerSpec extends Specification with Mockito {
def is =
"listAllCars should retrieve all cars" ! WithFreshMocks().listAllCarsShouldRetrieveAllCars
case class WithFreshMocks() {
val myServicesMock = mock[MyServices]
val myController = new MyController(myServicesMock)
def listAllCarsShouldRetrieveAllCars = {
val FakeGetRequest = FakeRequest() //fakeRequest needed by controller
mockListAllCarsAsReturningSomeCars()
val result = myController.listAllCars(FakeGetRequest).asInstanceOf[PlainResult] //passing fakeRequest to simulate a true request
assertOkResult(result).
and(there was one(myServicesMock).listAllCars()) //verify that there is one and only one call of listAllCars. If listAllCars would take any parameters that you expected to be called, you could have precise them.
}
private def mockListAllCarsAsReturningSomeCars() {
myServicesMock.listAllCars() returns List[Cars](Car("ferrari"), Car("porsche"))
}
private def assertOkResult(result: PlainResult) = result.header.status must_== 200
}
So, I came up with a cake pattern and mockito based solution:
given the service:
trait Service {
def indexMessage : String
}
trait ServiceImpl {
def indexMessage = {
"Hello world"
}
}
Then the controller looks like:
object Application extends ApplicationController
with ServiceImpl {
def template = views.html.index.apply
}
trait ApplicationController extends Controller
with Service {
def template: (String) => play.api.templates.Html
def index = Action {
Ok(template("controller got:" + indexMessage))
}
}
And the test looks like:
class ApplicationControllerSpec extends Specification with Mockito {
"cake ApplicationController" should {
"return OK with the results of the service invocation" in {
val expectedMessage = "Test Message"
val m = mock[(String) => play.api.templates.Html]
object ApplicationControllerSpec extends ApplicationController {
def indexMessage = expectedMessage
def template = m
}
val response = ApplicationControllerSpec.index(FakeRequest())
status(response) must equalTo(OK)
there was one(m).apply(Matchers.eq("controller got:" + expectedMessage))
}
}
}
I had a lot of trouble getting Mockito working.
It requires an extra dependency and I had a lot of trouble working out how to use the matchers in scala (I'm quite comfortable using it in java)
Ultimately I think the above answer is better, avoid using String and other primitive types where you can wrap them in task specific types, then you get compiler warnings.
Also I would generally avoid doing things like the "controller got:" prefixing in the controller.
It's there in this case so I can verify that it went through, in the real world that should be done by some other component (controllers are just for plumbing IMO)
In one of my unit tests, I am having some difficulty getting a mocked method to executed. I have the following test code:
void testExample() {
def mockICFService = new MockFor(ICFService)
...
//Mock the methods
controller.metaClass.icfList = { def person ->
println "icfList"
return [new IC(conceptId:'12345')]
}
mockICFService.demand.getAllIC(1..1) { def id, def withHist, def appId ->
println "mocking service"
return new Person()
}
...
def model = controller.detail()
}
Inside of detail in my controller class I create a Person via the ICFService's getAllIC(). This part works correctly. Later in the function, however, there is a call to icfList (which is defined in the controller). Through println's I have determined that the call is still being made, although it is returning an empty array. I believe that this is because the array is populated based on data in the servletContext, but in Unit Testing there is no access to that (hence my trying to mock it out).
Does anyone know how to force the test to use the mocked version of controller.icfList instead of calling the actual method in controller?
When I try your code, what blows up for me is the mocked service, and the part that works properly is the mocked-out icfList() method. The opposite of your observation, interestingly. For what it's worth, here's what I did:
First replace new MockFor() class instantiation with the mockFor() method. Then you need to inject the mock service into the controller.
def mockICFService = mockFor(ICFService)
controller.iCFService = mockICFService.createMock()
By doing the above, only the mocked versions of icfList() and getAllIC() get called, so you are not using the servletContext at all. Check out the Grails testing documentation for more info.
and thank you in advance for any and all your assistance.
I have a method that I'm trying to test.
Within this method is a call to UserMembership.Validate()
//custom override but the code isn't functional yet and is outside the scope of the test.
I want to therefore mock (using moq) the return result so that the actual test of the method can succeed.
Here is the code
public LoginResponse Login(LoginRequest request)
{
var response = new LoginResponse(request.RequestId);
// Validate client tag and access token
if (!ValidateRequest(request, response, Validate.ClientTag | Validate.AccessToken))
return response;
if (!UserMembership.ValidateUser(request.UserName, request.Password))
{
response.Acknowledge = AcknowledgeType.Failure;
response.Messages = "Invalid username and/or password.";
//response.MessageCode = -4;
return response;
}
_userName = request.UserName;
return response;
}
So, my test is for LoginResponse() but I want to 'fake' the UserMembership return value (bool) to true...
Simple enough I'm sure for you guys.
TIA, Hugh.
You could probably re-title your question to "How do you use a mocking framework with unit testing 99% of the time," because you're right on track for doing just that - a very typical usage.
You're going to want to extract an interface from your UserMembership class (right click inside the class, select "refactor" and then "extract interface."), then use Moq to create mock instances of that interface for use within your tests. Then you can use Moq to "setup" the behavior of that mock to do anything you want it to during your test. The syntax would look like this:
var userMembershipMock = new Mock<IUserMembership>();
userMembershipMock.Setup(m=> m.ValidateUser(It.Is<string>(str=> str == "myUserName"), It.Is<string>(str=> str == "myPassword"))).Returns(true);
Then you would create a new instance of your class, passing in your mock instance of IUserMembership (but since you'll make your class's constructor takes an argument of the interface type, your class won't care whether you're passing it a mock or an actual UserMembership instance
MyClass myClass = new MyClass(userMembershipMock.Object);
after which you could begin actually testing the behavior of your MyClass:
var request = new LoginRequest { UserName = "myUserName", Password = "myPassword" };
LoginResponse response = myClass.Login(request);
And then you can assert that your class's response is what you expect:
Assert.AreEqual(AcknowledgeType.Success, response.Acknowledge);
or you can verify that your mock's method (or property) was invoked as you expected:
userMembershipMock.Verify(m=> m.ValidateUser(It.Is<string>(str=> str == "myUserName"), It.Is<string>(str=> str == "myPassword")), Times.Once());
and so on.
The Moq quick start page is kind of sort of a one-page read, and can teach you 99% of everything that you need to know to use it.
The only way I can think of to mock UserMembership in this case (assuming it's not a property) is to use an IoC framework like Castle Windsor or Ninject. When you use an IoC container you would refactor your calls to UserMembership into an interface (IUserMembership) and use the container to provide an implementation:
if (Container.Resolve<IUserMembership>().ValidateUser(request.UserName, request.Password))
Then in your unit test Setup you would register the implementation of IUserMembership to be the mock object:
var mock = new Mock<IUserMembership>();
Container.Register<IUserMemberhip>().Instance(mock.Object);
You would have to also create a production implementation. If this is the standard UserMembership class, this implementation will probably do nothing other than UserMembership. Although, there are other ways to mimic this kind of duck typing.
If I have a method that calls itself under a certain condition, is it possible to write a test to verify the behavior? I'd love to see an example, I don't care about the mock framework or language. I'm using RhinoMocks in C# so I'm curious if it is a missing feature of the framework, or if I'm misunderstanding something fundamental, or if it is just an impossibility.
a method that calls itself under a certain condition, is it possible to write a test to verify the behavior?
Yes. However, if you need to test recursion you better separate the entry point into the recursion and the recursion step for testing purposes.
Anyway, here is the example how to test it if you cannot do that. You don't really need any mocking:
// Class under test
public class Factorial
{
public virtual int Calculate(int number)
{
if (number < 2)
return 1
return Calculate(number-1) * number;
}
}
// The helper class to test the recursion
public class FactorialTester : Factorial
{
public int NumberOfCalls { get; set; }
public override int Calculate(int number)
{
NumberOfCalls++;
return base.Calculate(number)
}
}
// Testing
[Test]
public void IsCalledAtLeastOnce()
{
var tester = new FactorialTester();
tester.Calculate(1);
Assert.GreaterOrEqual(1, tester.NumberOfCalls );
}
[Test]
public void IsCalled3TimesForNumber3()
{
var tester = new FactorialTester();
tester.Calculate(3);
Assert.AreEqual(3, tester.NumberOfCalls );
}
Assuming you want to do something like get the filename from a complete path, for example:
c:/windows/awesome/lol.cs -> lol.cs
c:/windows/awesome/yeah/lol.cs -> lol.cs
lol.cs -> lol.cs
and you have:
public getFilename(String original) {
var stripped = original;
while(hasSlashes(stripped)) {
stripped = stripped.substringAfterFirstSlash();
}
return stripped;
}
and you want to write:
public getFilename(String original) {
if(hasSlashes(original)) {
return getFilename(original.substringAfterFirstSlash());
}
return original;
}
Recursion here is an implementation detail and should not be tested for. You really want to be able to switch between the two implementations and verify that they produce the same result: both produce lol.cs for the three examples above.
That being said, because you are recursing by name, rather than saying thisMethod.again() etc., in Ruby you can alias the original method to a new name, redefine the method with the old name, invoke the new name and check whether you end up in the newly defined method.
def blah
puts "in blah"
blah
end
alias blah2 blah
def blah
puts "new blah"
end
blah2
You're misunderstanding the purpose of mock objects. Mocks (in the Mockist sense) are used to test behavioral interactions with dependencies of the system under test.
So, for instance, you might have something like this:
interface IMailOrder
{
void OrderExplosives();
}
class Coyote
{
public Coyote(IMailOrder mailOrder) {}
public void CatchDinner() {}
}
Coyote depends on IMailOrder. In production code, an instance of Coyote would be passed an instance of Acme, which implements IMailOrder. (This might be done through manual Dependency Injection or via a DI framework.)
You want to test method CatchDinner and verify that it calls OrderExplosives. To do so, you:
Create a mock object that implements IMailOrder and create an instance of Coyote (the system under test) by passing the mock object to its constructor. (Arrange)
Call CatchDinner. (Act)
Ask the mock object to verify that a given expectation (OrderExplosives called) was met. (Assert)
When you setup the expectations on the mock object may depend on your mocking (isolation) framework.
If the class or method you're testing has no external dependencies, you don't need (or want) to use mock objects for that set of tests. It doesn't matter if the method is recursive or not.
You generally want to test boundary conditions, so you might test a call that should not be recursive, a call with a single recursive call, and a deeply-recursive call. (miaubiz has a good point about recursion being an implementation detail, though.)
EDIT: By "call" in the last paragraph I meant a call with parameters or object state that would trigger a given recursion depth. I'd also recommend reading The Art of Unit Testing.
EDIT 2: Example test code using Moq:
var mockMailOrder = new Mock<IMailOrder>();
var wily = new Coyote(mockMailOrder.Object);
wily.CatchDinner();
mockMailOrder.Verify(x => x.OrderExplosives());
There isn't anything to monitor stack depth/number of (recursive) function calls in any mocking framework I'm aware of. However, unit testing that the proper mocked pre-conditions provide the correct outputs should be the same as mocking a non-recursive function.
Infinite recursion that leads to a stack overflow you'll have to debug separately, but unit tests and mocks have never gotten rid of that need in the first place.
Here's my 'peasant' approach (in Python, tested, see the comments for the rationale)
Note that implementation detail "exposure" is out of question here, since what you are testing is the underlying architecture which happens to be utilized by the "top-level" code. So, testing it is legitimate and well-behaved (I also hope, it's what you have in mind).
The code (the main idea is to go from a single but "untestable" recursive function to an equivalent pair of recursively dependent (and thus testable) functions):
def factorial(n):
"""Everyone knows this functions contract:)
Internally designed to use 'factorial_impl' (hence recursion)."""
return factorial_impl(n, factorial_impl)
def factorial_impl(n, fct=factorial):
"""This function's contract is
to return 'n*fct(n-1)' for n > 1, or '1' otherwise.
'fct' must be a function both taking and returning 'int'"""
return n*fct(n - 1) if n > 1 else 1
The test:
import unittest
class TestFactorial(unittest.TestCase):
def test_impl(self):
"""Test the 'factorial_impl' function,
'wiring' it to a specially constructed 'fct'"""
def fct(n):
"""To be 'injected'
as a 'factorial_impl''s 'fct' parameter"""
# Use a simple number, which will 'show' itself
# in the 'factorial_impl' return value.
return 100
# Here we must get '1'.
self.assertEqual(factorial_impl(1, fct), 1)
# Here we must get 'n*100', note the ease of testing:)
self.assertEqual(factorial_impl(2, fct), 2*100)
self.assertEqual(factorial_impl(3, fct), 3*100)
def test(self):
"""Test the 'factorial' function"""
self.assertEqual(factorial(1), 1)
self.assertEqual(factorial(2), 2)
self.assertEqual(factorial(3), 6)
The output:
Finding files...
['...py'] ... done
Importing test modules ... done.
Test the 'factorial' function ... ok
Test the 'factorial_impl' function, ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK