Testing a method provided by autoload with Test::More - perl

I have a factory class which provides a bunch of similar methods by using autoload. For a longer list of different object types it can do things like
Factory->objects();
Factory->object(23);
Factory->object(name => "foo");
Now I want to write a test for this class. I started with something like this:
use Test::More;
BEGIN { use_ok 'Factory' }
my $objects = Factory->objects;
# more tests following ...
The test fails in the line with Factory->objects because it implicitly checks if Factory can do objects(). I could not find some documentation for this. But if I run the same call in a non-testing script it works perfectly.
How to test this?
Update: ARGH, I've just recognized I put all of this in the test for the Factory model class in my Catalyst app. Well, this model class is an Adapter for the Factory class in my external model (which I actually intended to test). The work perfectly for the model itself. Still would appreciate to know how to test method from an adapted class. This is how the adapter class looks like:
package MyCatalystApp::Model::Factory;
use Moose;
extends 'Catalyst::Model';
extends 'Catalyst::Model::Adaptor';
__PACKAGE__->config(class => 'MyModel::Factory');
MyModel::Factory is the same class as Factory in the original question. I skipped the difference between Catalyst and the model in the original question for simplification.

You should simply add "use Factory;" before calling the tests (after use_ok).

Catalyst instantiates models (components) during setup_components by calling the COMPONENT method. I guess Catalyst::Model::Adaptor relies on this happening.
When you use MyCatalystApp::Model::Factory you can get away with calling my $factory = MyCatalystApp::Model::Factory->COMPONENT() from within tests instead of new() to make them work.

Related

Proper way to customize Spark ML estimator (e.g. GaussianMixture) by modified its private method?

My code use apache.ml.clustering.GaussianMixture, but its init method private def initRandom(...) does not work well, so I want to customize a new init method.
At first I want to "extends" class GuassianMixture, but initRandom is a private method.
Then I tried another way, it is to set initial GMM, but sadly source code says that TODO: SPARK-15785 Support users supplied initial GMM.
I've also tried to copy the code of class GuassianMixture for my custom class, but there are too many things attached to it. GaussianMixture.scala comes with sort of classes and traits, some of which are only accessible within ML packages.
I solved it by myself. Here is my solution.
I created class CustomGaussianMixture which extends GaussianMixture from official package org.apache.spark.ml.clustering.
And within my project, I created a new package, also named as org.apache.spark.ml.clustering(to prevent deal with scope of sort of complexity classes/traits/objects in org.apache.spark.ml.clustering). And place my custom class in it.
The next thing is to override the method(fit) call initRandom, a non-private method, so I can override it. Specifically, Just write my new init method in class CustomGaussianMixture, and copy method fit from official source code in GaussianMixture.scala to class CustomGaussianMixture, remember to modify code in CustomGaussianMixture.fit() to call my custom init method.
At last, just use CustomGaussianMixture instead of GaussianMixture when needed.

Mocking docblock annotations in PHPUnit

I am building an app that implements custom docblock annotations using the Doctrine Annotations library.
For PHPUnit testing, is it possible to create a mocked class that has mock docblocks?
From this answer, I learned how to mock a class, like so:
$foo = $this->getMockBuilder('nonexistant')
->setMockClassName('TestClass')
->getMock();
Is there a way to mock a docblock? Building on the class example, Something like this is what I imagine:
$foo = $this->getMockBuilder('nonexistant')
->setMockClassName('TestClass')
->setMockClassDocblock('/** #SomeAnnotation("foo") */')
->getMock();
If not - is there anything I can do besides just creating actual test classes?
There is no way to mock a docblock. If you can make the case that there should be then please open a ticket.

How can I fake a Class used insite SUT using FakeItEasy

Am having a little trouble understanding what and what cannot be done using FakeItEasy. Suppose I have a class
public class ToBeTested{
public bool MethodToBeTested(){
SomeDependentClass dependentClass = new SomeDependentClass();
var result = dependentClass.DoSomething();
if(result) return "Something was true";
return "Something was false";
}
}
And I do something like below to fake the dependent class
var fakedDepClass = A.Fake<DependentClass>();
A.CallTo(fakedDepClass).WithReturnType<bool>().Returns(true);
How can i use this fakedDepClass when am testing MethodToBeTested. If DependentClass was passed as argument, then I can pass my fakedDepClass, but in my case it is not (also this is legacy code that I dont control).
Any ideas?
Thanks
K
Calling new SomeDependentClass() inside MethodToBeTested means that you get a concrete actual SomeDependentClass instance. It's not a fake, and cannot be a FakeItEasy fake.
You have to be able to inject the fake class into the code to be tested, either (as you say) via an argument to MethodToBeTested or perhaps through one of ToBeTested's constructors or properties.
If you can't do that, FakeItEasy will not be able to help you.
If you do not have the ability to change ToBeTested (and I'd ask why you're writing tests for it, but that's an aside), you may need to go with another isolation framework. I have used TypeMock Isolator for just the sort of situation you describe, and it did a good job.

How to call constructor with interface arguments when mocking a concrete class with Moq

I have the following class, which uses constructor injection:
public class Service : IService
{
public Service(IRepository repository, IProvider provider) { ... }
}
For most methods in this class, I simply create Moq mocks for IRepository and IProvider and construct the Service. However, there is one method in the class that calls several other methods in the same class. For testing this method, instead of testing all those methods together, I want to test that the method calls those methods correctly and processes their return values correctly.
The best way to do this is to mock Service. I've mocked concrete classes with Moq before without issue. I've even mocked concrete classes that require constructor arguments with Moq without issue. However, this is the first time I've needed to pass mocked arguments into the constructor for a mocked object. Naturally, I tried to do it this way:
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Mock<Service>(repository.Object, provider.Object);
However, that does not work. Instead, I get the following error:
Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: My.Namespace.Service.
Could not find a constructor that would match given arguments:
Castle.Proxies.IRepository
Castle.Proxies.IProvider
This works fine if Service's constructor takes simple arguments like ints and strings, but not if it takes interfaces that I'm mocking. How do you do this?
Why are you mocking the service you are testing? If you are wishing to test the implementation of the Service class (whether that be calls to mocked objects or not), all you need are mocks for the two interfaces, not the test class.
Instead of:
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Mock<Service>(repository.Object, provider.Object);
Shouldn't it be this instead?
var repository = new Mock<IRepository>();
var provider = new Mock<IProvider>();
var service = new Service(repository.Object, provider.Object);
I realize that it is possible to mock concrete objects in some frameworks, but what is your intended purpose? The idea behind mocking something is to remove the actual implementation so that it does not influence your test. But in your question, you have stated that you wish to know that certain classes are called on properly, and then you wish to validate the results of those actions. That is undoubtedly testing the implementation, and for that reason, I am having a hard time seeing the goals of mocking the concrete object.
I had a very similar problem when my equivalent of Service had an internal constructor, so it was not visible to Moq.
I added
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
to my AssemblyInfo.cs file for the implementing project. Not sure if it is relevant, but I wanted to add a suggestion on the off chance that it helps you or someone else.
It must be old version issue, all is ok with latest version. Nick, Please check!
P.s.: I started bounty by misstake (I had wrong signature in my constructor).

How do I give global access to an object in Scala without making it a singleton or passing it to everything?

I have a Logger class that logs events in my application. While I only need one instance of the logger in this application, I want this class to be reusable, so I don't want to make it a singleton and couple it with my specific needs for this application.
I want to be able to access this Logger instance from anywhere in the application without having to create a new one every time or pass it around to every class that might need to log something. What I currently do is have an ApplicationUtils singleton that I use as the point of access for the application's Logger:
object ApplicationUtils {
lazy val log : Logger = new Logger()
}
Then I have a Loggable trait that I add to classes that need the Logger:
trait Loggable {
protected[this] lazy val log = ApplicationUtils.log
}
Is this a valid approach for what I am trying to accomplish? It feels a little hack-y. Is there a better approach I could be using? I'm pretty new to Scala.
Be careful when putting functionality in objects. That functionality is easily testable, but if you need to test clients of that code to make sure they interact with it correctly (via mocks and spies), you're stuck 'cause objects compile to final classes and thus cannot be mocked.
Instead, use this pattern:
trait T { /* code goes here */ }
object T extends T /* pass this to client code from main sources */
Now you can create Mockito mocks / spies for trait T in your test code, pass that in and confirm that the interactions of the code under test with the trait T code are what they should be.
If you have code that's a client of T and whose interactions with it don't require testing, you can directly reference object T.
To address what you're trying to do (rather than what you're asking), take a look at TypeSafe's scalalogging package. It provides a Logging trait that you can use like so:
class MyClass extends Logging {
logger.debug("This is very convenient ;-)")
}
It's a macro-based wrapper for SLF4J, so something like logger.debug(...) gets compiled as if (logger.isDebugEnabled) logger.debug(...).