flexunit: Parametrized tests - apache-flex

I am trying to run a parametrized tests... Was trying to implement it like it explained here:
http://docs.flexunit.org/index.php?title=Parameterized_Test_Styles
Here is what my test case looking
import org.flexunit.runners.Parameterized;
[RunWith("org.flexunit.runners.Parameterized")]
public class ArrayBasedStackTests
{
[Paremeters]
public static var stackProvider:Array = [new ArrayBasedStack(), new LinkedListBasedStack()] ;
private var _stack:IStack;
public function ArrayBasedStackTests(param:IStack)
{
_stack = param;
}
[Before]
public function setUp():void
{
}
[After]
public function tearDown():void
{
}
[Test ( description = "Checks isEmpty method of the stack. For empty stack", dataProvider="stackProvider" )]
public function isEmptyStackPositiveTest():void
{
var stack:IStack = _stack;
assertEquals( true, stack.isEmpty() );
}
But this code throws following initializing Error:
Error: Custom runner class org.flexunit.runners.Parameterized should
be linked into project and implement IRunner. Further it needs to have
a constructor which either just accepts the class, or the class and a
builder.
Need help to fix it
UPDATE
I've updated the code so it looks like this
[RunWith("org.flexunit.runners.Parameterized")]
public class ArrayBasedStackTests
{
private var foo:Parameterized;
[Parameters]
public static function stacks():Array
{
return [ [new ArrayBasedStack()], [new LinkedListBasedStack()] ] ;
}
[Before]
public function setUp():void
{
}
[After]
public function tearDown():void
{
}
[Test ( description = "Checks isEmpty method of the stack. For empty stack", dataProvider="stacks")]
public function isEmptyStackPositiveTest(stack:IStack):void
{
assertEquals( true, _stack.isEmpty() );
}
It works. But the result is a bit strange. I have 4 test executed instead of 2. (I have 2 items in data provider, so cant get why do I have 4 tests).
Output
http://screencast.com/t/G8DHbcjDUkJ

The [Parameters] meta-data specifies that the parameters are passed to the constructor of the test - so the test class is called for each parameter. You also have the dataProvider set for the specific test method, so the test method is also called once for each parameter. Two calls for the test, and two calls to the method, ends up running four tests.
The solution is to either use [Parameters] meta-tag which specifies the data to use for the whole test class, or use the dataProvider for each test method, but not both with the same data at the same time.

You're missing the static reference to Paramaterized, as shown here:
import org.flexunit.runners.Parameterized;
[RunWith("org.flexunit.runners.Parameterized")]
public class MyTestNGTest
{
private var foo:Parameterized;
...
Basically, that error means that the [Runner] defined isn't available at runtime, which occurs if there is no static reference in the class to cause it to get linked in.
In FlexUnit 4.5.1, this approach changed to using [Rule]'s like so:
public class MyTestNGTest
{
[Rule]
public function paramaterizedRule:ParamaterizedRule = new ParamaterizedRule();
...
}
However, I can't seem to see an actual implementation of IMethodRule for paramaterized tests (that example is fictional).

Related

Symfony - configure class from `service.yaml` with static default value

I am trying to create a Class that can be call from anywhere in the code.
It accepts different parameters that can be configured from the constructor (or setters).
This Class will be shared between several projects, so I need to be able to easily configure it once and use the same configuration (or different/specific one) multiple times.
Here's my class:
namespace Allsoftware\SymfonyBundle\Utils;
class GdImageConverter
{
public function __construct(
?int $width = null,
?int $height = null,
int|array|null $dpi = null,
int $quality = 100,
string $resizeMode = 'contain',
) {
$this->width = $width ? \max(1, $width) : null;
$this->height = $height ? \max(1, $height) : null;
$this->dpi = $dpi ? \is_int($dpi) ? [\max(1, $dpi), \max(1, $dpi)] : $dpi : null;
$this->quality = \max(-1, \min(100, $quality));
$this->resizeMode = $resizeMode;
}
}
Most of the time, the constructor parameters will be the same for ONE application.
So I thought of using a private static variable that corresponds to itself, but already configured.
So I added the $default variable:
namespace Allsoftware\SymfonyBundle\Utils;
class GdImageConverter
{
private static GdImageConverter $default;
public function __construct(
?int $width = null,
?int $height = null,
int|array|null $dpi = null,
int $quality = 100,
string $resizeMode = 'contain',
) {
// ...
}
public static function setDefault(self $default): void
{
self::$default = $default;
}
public static function getDefault(): self
{
return self::$default ?? self::$default = new self();
}
}
Looks like a Singleton but not really.
To set it up once and use GdImageConverter::getDefault() to get it, I wrote these lines inside the service.yaml file:
services:
default.gd_image_converter:
class: Allsoftware\SymfonyBundle\Utils\GdImageConverter
arguments:
$width: 2000
$height: 2000
$dpi: 72
$quality: 80
$resizeMode: contain
Allsoftware\SymfonyBundle\Utils\GdImageConverter:
calls:
- setDefault: [ '#default.gd_image_converter' ]
ATE when calling GdImageConverter::getDefault(), it does not correspond to the default.gd_image_converter service.
$default = GdImageConverter::getDefault();
$imageConverter = new GdImageConverter(2000, 2000, 72, 80);
dump($default);
dump($imageConverter);
die();
And when debugging self::$default inside getDefault(), it's empty.
What am I doing wrong ?
Note: When I change the calls method setDefault to a non-existing method setDefaults, symfony tells me that the method is not defined.
Invalid service "Allsoftware\SymfonyBundle\Utils\GdImageConverter": method "setDefaults()" does not exist.
Thank you!
Decided to post a new and hopefully more coherent answer.
The basic problem is that GdImageConverter::getDefault(); returns an instance for which all the arguments are null. And that is because the Symfony container only creates services when they are asked for (aka injected). setDefault is never called so new self() is used.
There is a Symfony class called MimeTypes which employs a similar pattern but it does not try to customize the service so it does not matter.
There is a second problem with the way the GdImageConverter service is configured. It will basically inject a 'null' version even though it does set the default instant correctly.
To fix the second problem you need to call setDefault with the current service and just get rid of default.gd_image_converter unless you need it for something else:
services:
App\Service\GdImageConverter:
class: App\Service\GdImageConverter
public: true
arguments:
$width: 2000
$height: 2000
$dpi: 72
$quality: 80
$resizeMode: contain
calls:
- setDefault: [ '#App\Service\GdImageConverter' ]
As a side note, the static method setDefault will be called dynamically. This is a bit unusual but it is legal in PHP and Symfony does it for other classes.
Next we need to ensure the service is always instantiated. This is a rare requirement and I don't think there is a default way to do so. But using Kernel::boot works:
# src/Kernel.php
class Kernel extends BaseKernel
{
use MicroKernelTrait;
public function boot()
{
parent::boot();
$this->container->get(GdImageConverter::class);
}
}
This ensures that the default service is set for both commands and web applications. GdImageConverter::getDefault(); can now be called at anytime and will return the initialized service. Notice that the service had to be declared public for Container::get to work.
You could stop here but always creating a service even though you probably don't usually need it is kind of annoying. It is possible to avoid doing that by injecting the container itself into your class.
This definitely violates Symfony's recommended practices and if the reader feels they need to downvote the answer for even suggesting it then do what you need to do. However the Laravel framework uses this approach (called facades) on a routine basis and those apps somehow manage to work.
use Psr\Container\ContainerInterface;
class GdImageConverter
{
private static GdImageConverter $default;
private static ContainerInterface $container; // Add this
public static function setContainer(ContainerInterface $container)
{
self::$container = $container;
}
public static function getDefault(): self
{
//return self::$default ?? self::$default = new self();
return self::$default ?? self::$default = self::$container->get(GdImageConverter::class);
}
}
# Kernel.php
public function boot()
{
parent::boot();
GdImageConverter::setContainer($this->container);
}
And now we are back to lazy instantiation.
And while I won't provide the details you could eliminate the need to inject the container as well as making the service public by injecting a GdImageConverterServiceLocater.

How can I easily wrap the StackExchange.Redis `IDatabase`?

I want to override methods for specific commands on the IDatabase to modify the results.
FT.SEARCH should never return duplicate keys but it can when there is some sort of corruption.
I am using another library that calls FT.SEARCH in IDatabase so this part can only be done by changing IDatabase.
I can autogenerate a wrapper and then use this, but it would need to be maintained and updated every time the IDatabase interface changes. It would be unfortunate to need to update the wrapper class even when I didn't need to override the method that changed in IDatabase. Is there another option that would have similar performance that this wrapper does?
Assume I had a class called DatabaseWrapper all methods were virtual and that was in another package example code would look like:
public sealed class MyDatabaseOverrides: DatabaseWrapper
{
private const string RediSearchSearchCommandName = "FT.SEARCH";
public MyDatabaseOverrides(IDatabase wrapped) : base(wrapped)
{
}
public override Task<RedisResult> ExecuteAsync(string command, params object[] args)
{
var resultTask = base.ExecuteAsync(command, args);
if (string.Equals(RediSearchSearchCommandName, command, StringComparison.OrdinalIgnoreCase))
{
return SkipAndLogDuplicateKeys(resultTask);
}
return resultTask;
}
private async Task<RedisResult> SkipAndLogDuplicateKeys(Task<RedisResult> resultTask)
{
// implementation omitted for brevity
return await resultTask;
}
}

How to setup Moq to execute some methods of a Moq

I have a test where I pass in an object like so:
var repo = new ActualRepo();
var sut = new Sut(repo);
In my test, Repo has one method that I need to actually execute, whilst another method I want to mock out and not execute.
So for example, take this pseudocode:
var repo = new Mock<IRepo>();
repo.Setup(m => m.MethodIWantToCall()).WillBeExecuted();
repo.Setup(m => m.MethodIWantToMock()).Returns(false);
Using Moq, is this possible and how can it be done?
EDIT:
I've used TypeMock in the past and you can do something like.
Isolator.When(() => repo.MethodToIgnore()).WillBeIgnored();
Isolator.When(() => repo.MethodToActuallyRun()).WillBeExecuted();
Not too sure from the question if this is useful but it is possible to partially mock an object if the method that you want to mock is virtual.
public class Foo {
public string GetLive() {
return "Hello";
}
public virtual string GetMock() {
return "Hello";
}
}
public class Snafu {
private Foo _foo;
public Snafu(Foo foo) {
_foo = foo;
}
public string GetMessage() {
return string.Format("{0} {1}", _foo.GetLive(), _foo.GetMock());
}
}
[TestMethod]
public void NotMocked() {
var snafu = new Snafu(new Foo());
Assert.AreEqual("Hello Hello", snafu.GetMessage());
}
[TestMethod]
public void Mocked() {
var mockFoo = new Mock<Foo>();
mockFoo.Setup(mk => mk.GetMock()).Returns("World");
var snafu = new Snafu(mockFoo.Object);
Assert.AreEqual("Hello World", snafu.GetMessage());
}
You can't do this with Moq if you use the same object unless one of the method is virtual and you are basing your mock on a type rather than an interface.
That's because when you are passing a mock object based on an interface, you aren't passing a real object so it does not have access to the real methods of the object.
You are passing a dynamic proxy which will respond to methods it has been setup to respond to.
I believe TypeMock rewrites the assemblies at runtime to achieve this, something Moq definitively doesn't do.
If you want to achieve similar results with Moq:
You could mock both methods
You would have to extract both methods to different dependencies so as to mock one dependency and not the other.
You could have the method you need mocked be virtual, which would be the solution I would prefer.
EDIT : I edited my answer for correctness after reading AlanT's answer.

How to Verify another method in the class was called using Moq

This seems like something simple but I can't seem to get it to work.
I have a class with a Save method that simply calls another method ShouldBeCalled(). I want to verify that if I call Save() that the other method ShouldBeCalled() is executed at least once. I thought that I could do the following.
public class ClassA
{
public virtual void Save()
{
ShouldBeCalled();
}
public virtual void ShouldBeCalled()
{
//This should get executed
}
}
[TestFixture]
public class ClassA_Test
{
[Test]
public void Save_Should_Call_ShouldBeCalled()
{
var mockClassA = new Mock<ClassA>();
mockClassA.Object.Save();
mockClassA.Verify(x => x.ShouldBeCalled(), Times.AtLeastOnce());
}
}
But I get the exception "Expected invocation on the mock at least once, but was never performed: x => x.ShouldBeCalled()"
It is just a guess but Is Moq overriding the Save() method with it's own version which ignores anything I have inside the real object's Save() method.
You are having this problem because you are mocking what you are testing. This doesn't make sense.
You are correct that Moq will replace the implementation of your method with its own. The reason is you are supposed to use Moq to mock things the class you are testing calls, not the class you are testing itself.
This test would be appropriate if your code were designed thusly:
public class ClassA
{
BusinessLogicClass bl;
public ClassA(BusinessLogicClass bl)
{
this.bl = bl;
}
public void Save()
{
bl.ShouldBeCalled();
}
}
public class BusinessLogicClass
{
public virtual void ShouldBeCalled()
{
//This should get executed
}
}
And here is the correct test of that method now:
[TestFixture]
public class ClassA_Test
{
[Test]
public void Save_ShouldCallShouldBeCalled()
{
//Arrange
var mockBLClass = new Mock<BusinessLogicClass>();
mockBLClass.Setup(x => x.ShouldBeCalled()).Verifyable();
//Act
ClassA classA = new ClassA(mockBLClass.Object);
classA.Save();
//Assert
mockBLClass.VerifyAll();
}
}
The key lesson here is that you mock/stub what your test needs to run, not what you are testing itself.
Hope this helps,
Anderson
Try using the CallBase = true and then false. I ran your code and it works.
var mockClassA = new Mock<ClassA>();
mockClassA.CallBase = true;
mockClassA.Object.Save();
mockClassA.CallBase = false;
mockClassA.Verify(x => x.ShouldBeCalled(), Times.AtLeastOnce());
Yes, this can be done. However, you need to add a line of code to have Moq track whether or not the ShouldBeCalled method was indeed called.
Something like the following will work:
var mockClassA = new Mock<ClassA>();
mockClassA.Setup(x => x.ShouldBeCalled()).Verifiable();
mockClassA.Object.Save();
mockClassA.Verify(x => s.ShouldBeCalled(), Times.AtLeastOnce());
The Setup method sets up expectations. When you call Verify, you are asking Moq to verify these expectations. If you don't make a Setup call to create expectations for the ShouldBeCalled method, then Moq doesn't consider it to be trackable and will therefore fail hard when you try to Verify it.
You can stub methods in the system under test using CallBase.
[TestFixture]
public class ClassA_Test
{
[Test]
public void Save_Should_Call_ShouldBeCalled()
{
// Arrange
var mockClassA = new Mock<ClassA>();
mockClassA.CallBase = true; // this will call real methods unless the method is mocked/stubbed.
mockClassA.Setup(a => a.ShouldBeCalled());
// Act
mockClassA.Save();
// Assert
mockClassA.Verify(a => a.ShouldBeCalled(), Times.Once());
}
}

Mocking a base class method call with Moq

I am modifiying a class method which formats some input paramater dates which are subsequently used as params in a method call into the base class (which lives in another assembly).
I want to verify that the dates i pass in to my method are in the correct format when they are passed to the base class method so i would like to Moq the base class method call. Is this possible with Moq?
As of 2013 with latest Moq you can. Here is an example
public class ViewModelBase
{
public virtual bool IsValid(DateTime date)
{
//some complex shared stuff here
}
}
public class MyViewModel : ViewModelBase
{
public void Save(DateTime date)
{
if (IsValid(date))
{
//do something here
}
}
}
public void MyTest()
{
//arrange
var mockMyViewModel = new Mock<MyViewModel>(){CallBase = true};
mockMyViewModel.Setup(x => x.IsValid(It.IsAny<DateTime>())).Returns(true);
//act
mockMyViewModel.Object.Save();
//assert
//do your assertions here
}
If I understand your question correctly, you have a class A defined in some other assembly, and then an class B implemented more or less like this:
public class B : A
{
public override MyMethod(object input)
{
// Do something
base.MyMethod(input);
}
}
And now you want to verify that base.MyMethod is called?
I don't see how you can do this with a dynamic mock library. All dynamic mock libraries (with the exception of TypeMock) work by dynamically emitting classes that derive from the type in question.
In your case, you can't very well ask Moq to derive from A, since you want to test B.
This means that you must ask Moq to give you a Mock<B>. However, this means that the emitted type derives from B, and while it can override MyMethod (which is still virtual) and call its base (B.MyMethod), it has no way of getting to the original class and verify that B calls base.MyMethod.
Imagine that you have to write a class (C) that derives from B. While you can override MyMethod, there's no way you can verify that B calls A:
public class C : B
{
public override MyMethod(object input)
{
// How to verify that base calls its base?
// base in this context means B, not A
}
}
Again with the possible exception of TypeMock, dynamic mock libraries cannot do anything that you cannot do manually.
However, I would assume that calling the base method you are trying to verify has some observable side effect, so if possible, can you use state-based testing instead of behaviour-based testing to verify the outcome of calling the method?
In any case, state-based testing ought to be your default approach in most cases.
Agree with Mark, it's not possible using Moq.
Depending on your situation you may consider swithcing from inheritance to composition. Then you'll be able to mock the dependency and verify your method. Of course in some cases it just might not worth it.
wrap the base class method in a method and setup that method
e.g.
public class B : A
{
public virtual BaseMyMethod(object input)
{
// Do something
base.MyMethod(input);
}
public override MyMethod(object input)
{
// Do something
BaseMyMethod(input);
}
}
and now Setup the BaseMyMethod
It is quite possible mocking base class. But you will have to modify target class.
For ex. DerivedClass extends BaseClass.
BaseClass has methods MethodA(), MethodB(), MethodC()...
The DerivedClass has this method:
void MyMethod() {
this.MethodA();
this.MethodB();
this.MethodC();
}
You want to mock base class in order to validate that all MethodA(), MethodB(), MethodC() are being called inside MyMethod().
You have to create a field in the DerivedClass:
class DerivedClass {
private BaseClass self = this;
...
}
And also You have to modify the MyMethod():
void MyMethod() {
self.MethodA();
self.MethodB();
self.MethodC();
}
Also add a method, which can inject the this.self field with Mock object
public void setMock(BaseClass mock) {
this.self = mock;
}
Now you can mock:
DerivedClass target = new DerivedClass ();
BaseClass mock = new Mock(typeof(BaseClass));
target.setMock(mock);
target.MyMethod();
mock.verify(MethodA);
mock.verify(MethodB);
mock.verify(MethodC);
Using this technic, you can also mock nested method calls.
I found this solution - ugly but it could work.
var real = new SubCoreClass();
var mock = new Mock<SubCoreClass>();
mock.CallBase = true;
var obj = mock.Object;
mock
.Setup(c => c.Execute())
.Callback(() =>
{
obj.CallBaseMember(typeof(Action), real, "Execute");
Console.WriteLine(obj.GetHashCode());
}
);
public static Delegate CreateBaseCallDelegate(object injectedInstance, Type templateDelegate, object instanceOfBase, string methodName)
{
var deleg = Delegate.CreateDelegate(templateDelegate, instanceOfBase, methodName);
deleg.GetType().BaseType.BaseType.GetField("_target", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(deleg, injectedInstance);
return deleg;
}
public static object CallBaseMember(this object injectedInstance, Type templateDelegate, object instanceOfBase, string methodName, params object[] arguments)
{
return CreateBaseCallDelegate(injectedInstance, templateDelegate, instanceOfBase, methodName).DynamicInvoke(arguments);
}

Resources