Can anyone help me how can i do code coverage for below property using Moq -
public class Test
{
public IEmployee Employee
{
get
{
return TypeFactory.Resolve(typeof(IEmployee)) as IEmployee;
}
}
}
Thanks in advance.
You generally don't do code coverage with Moq.
You may setup the property with MoQ, to use a component depending on this property with .setupget();
Or if you want to test the getter itself(cover it by a test), make a test that calls for it. Than you'll ned to setup with MoQ the component it depends on - TypeFactory in your example.
Related
I'm using AssertJ to test web using fluentlenium and extent reports for reporting the results.
I asked before the question but forgot to mention the use of AssertJ.
The provided answer was to extend soft assert and that it has onAssertFailure function.
Is there anything like this for AssertJ soft assertions? Or is there another solution to bypass it?
In the next AssertJ version (2.5.0) you will have access to all soft assertions errors (see this commit).
Hope it helps
In a future release of assertJ a method wasSuccess() is added (as can be seen on git history), but it is not yet available in the current release.
When this method is added you can do something like this:
public class AssertjSoftAssert extends SoftAssertions {
private void checkFailure() {
if(!wasSuccess()) {
onFailure();
}
}
private void onFailure() {
//doFailureStuff
}
#Override
public BigDecimalAssert assertThat(BigDecimal actual) {
BigDecimalAssert assertion = super.assertThat(actual);
checkFailure();
return assertion;
}
#Override
public BooleanAssert assertThat(boolean actual) {
BooleanAssert assertion = super.assertThat(actual);
checkFailure();
return assertion;
}
}
Do note, however, that you will have to override EVERY assertion method in the SoftAssertions class like I've shown you with the examples here. And also if new Assertions are added to the SoftAssertions class you will have to override those as well. This is the best solution I could find right now, but won't work until assertj is updated either.
EDIT: Actually I am not sure this would even work because I am not sure wasSuccess() will return true after every successvul softassert or only after throwing assertAll() but I can't test this obviously as the feature isn't out yet.
Bonus: The commit that added wasSuccess()
I have the following method I need to test with Moq. The problem is that each method called in the switch statement is private, including the PublishMessage at the end. But this method (ProcessMessage) is public. How can I test this so that I can ensure the calls are made depending on the parameter? Note that I'm not testing the private methods, I just want to test the "calls". I'd like to mock these private methods and check if they are called using Setup, but Moq does not support mocking private methods.
public void ProcessMessage(DispenserMessageDataContract dispenserMessage)
{
var transOptions = new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted };
using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew, transOptions))
{
switch (dispenserMessage.Type)
{
case DispenserMessageType.AckNack:
UpdateAckNackMessageQueue(dispenserMessage);
break;
case DispenserMessageType.FillRequest:
CreateFillRequestMessageQueue(dispenserMessage);
break;
case DispenserMessageType.FillEvent:
UpdateFillEventMessageQueue(dispenserMessage);
break;
case DispenserMessageType.RequestInventory:
CreateRequestInventoryMessageQueue(dispenserMessage);
break;
case DispenserMessageType.ReceiveInventory:
CreateReceiveInventoryMessageQueue(dispenserMessage);
break;
}
scope.Complete();
}
PublishMessage(dispenserMessage);
}
You will have to change those private methods to atleast protected virtual to mock them and then use mock.Protected to mock them(http://blogs.clariusconsulting.net/kzu/mocking-protected-members-with-moq/). You can't mock private methods.
Moq (and few other frameworks) uses Castle Project's DynamicProxy to generate proxies on the fly at run-time so that members of an object can be intercepted without modifying the code of the class. That interception can only be done on public virtual and protected virtual methods.
See below URL for more information:
http://www.castleproject.org/projects/dynamicproxy/
You could extract the private method in another class and make them public, then mock those with Moq and verify that they have been called.
Moq is for mocking properties and methods declared in interfaces and or abstract properties and methods in classes.
The idea behind Moq-testing is that you test the interactions between your class-under-test and the rest of the world (its dependencies). Moq does this by creating a "mocked" implementation of the interface or a derivative of the abstract class with the abstract methods implemented.
Moq cannot override existing implementation like your private methods. This is not how Moq works.
Either you should test "ProcessMessage" with all possible input and expected output or you should refactor your class to delegate the calls to interface methods that you can mock with Moq. Testing private methods is a bad concept anyway. They are kept private for a reason, which is to hide the implementation such that it can change at will.
I prefer to add additional class (*Helper) and move on all my private methods to public. Then you can easily test your methods directly. I didn't find more elegant way to do that.
In some cases, you may need to alter the behavior of private method inside the class you are unit testing. You will need to mock this private method and make it return what needed for the particular case. Since this private method is inside your class under test then mocking it is little more specific. You have to use spy object.
Spy object
A spy is a real object which mocking framework has access to. Spied objects are partially mocked objects. Some their methods are real some mocked. I would say use spy object with great caution because you do not really know what is happening underneath and whether are you actually testing your class or mocked version of it.
public class PowerMockDemo
{
public Point callPrivateMethod() {
return privateMethod(new Point(1, 1));
}
private Point privateMethod(Point point) {
return new Point(point.getX() + 1, point.getY() + 1);
}
}
Then you will mock the Spy object
Hope that will help you,
Best wishes
Does anyone have a good way to unit test an entity's validation constraints in Symfony2?
Ideally I want to have access to the Dependency Injection Container within the unit test which would then give me access to the validator service. Once I have the validator service I can run it manually:
$errors = $validator->validate($entity);
I could extend WebTestCase and then create a client to get to the container as per the docs however it doesn't feel right. The WebTestCase and client read in the docs as more of a facility to test actions as a whole and therefore it feels broken to use it to unit test an entity.
So, does anyone know how to either a) get the container or b) create the validator inside a unit test?
Ok since this got two votes I guess other people are interested.
I decided to get my shovel out and was pleasantly surprised (so far anyway) that this wasn't at all difficult to pull off.
I remembered that each Symfony2 component can be used in a stand alone mode and therefore that I could create the validator myself.
Looking at the docs at: https://github.com/symfony/Validator/blob/master/ValidatorFactory.php
I realised that since there was a ValidatorFactory it was trivial to create a validator (especially for validation done by annotations which I am, although if you look at the docblock on the page I linked above you'll also find ways to validate xml and yml).
First:
# Symfony >=2.1
use Symfony\Component\Validator\Validation;
# Symfony <2.1
use Symfony\Component\Validator\ValidatorFactory;
and then:
# Symfony >=2.1
$validator = Validation::createValidatorBuilder()->enableAnnotationMapping()->getValidator();
# Symfony <2.1
$validator = ValidatorFactory::buildDefault()->getValidator();
$errors = $validator->validate($entity);
$this->assertEquals(0, count($errors));
I hope this helps anyone else whose conscience wouldn't allow them to just use WebTestCase ;).
We end up rolling your own base test case to access the dependency container from within a test case. Here the class in question:
<?php
namespace Application\AcmeBundle\Tests;
// This assumes that this class file is located at:
// src/Application/AcmeBundle/Tests/ContainerAwareUnitTestCase.php
// with Symfony 2.0 Standard Edition layout. You may need to change it
// to fit your own file system mapping.
require_once __DIR__.'/../../../../app/AppKernel.php';
class ContainerAwareUnitTestCase extends \PHPUnit_Framework_TestCase
{
protected static $kernel;
protected static $container;
public static function setUpBeforeClass()
{
self::$kernel = new \AppKernel('dev', true);
self::$kernel->boot();
self::$container = self::$kernel->getContainer();
}
public function get($serviceId)
{
return self::$kernel->getContainer()->get($serviceId);
}
}
With this base class, you can now do this in your test methods to access the validator service:
$validator = $this->get('validator');
We decided to go with a static function instead of the class constructor but you could easily change the behavior to instantiate the kernel into the constructor directly instead of relying on the static method setUpBeforeClass provided by PHPUnit.
Also, keep in mind that each single test method in you test case won't be isolated fro, each others because the container is shared for the whole test case. Making modification to the container may have impact on you other test method but this should not be the case if you access only the validator service. However, this way, the test cases will run faster because you will not need to instantiate and boot a new kernel for each test methods.
For the sake of reference, we find inspiration for this class from this blog post. It is written in French but I prefer to give credit to whom it belongs :)
Regards,
Matt
I liked Kasheens answer, but it doesn't work for Symfony 2.3 anymore.
There are little changes:
use Symfony\Component\Validator\Validation;
and
$validator = Validation::createValidatorBuilder()->getValidator();
If you want to validate Annotations for instance, use enableAnnotationMapping() like below:
$validator = Validation::createValidatorBuilder()->enableAnnotationMapping()->getValidator();
the rest stays the same:
$errors = $validator->validate($entity);
$this->assertEquals(0, count($errors));
With Symfony 2.8, it seems that you can now use the AbstractConstraintValidatorTest class this way :
<?php
namespace AppBundle\Tests\Constraints;
use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest;
use AppBundle\Constraints\MyConstraint;
use AppBundle\Constraints\MyConstraintValidator;
use AppBundle\Entity\MyEntity;
use Symfony\Component\Validator\Validation;
class MyConstraintValidatorTest extends AbstractConstraintValidatorTest
{
protected function getApiVersion()
{
return Validation::API_VERSION_2_5;
}
protected function createValidator()
{
return new MyConstraintValidator();
}
public function testIsValid()
{
$this->validator->validate(null, new MyEntity());
$this->assertNoViolation();
}
public function testNotValid()
{
$this->assertViolationRaised(new MyEntity(), MyConstraint::SOME_ERROR_NAME);
}
}
You have got a good sample with the IpValidatorTest class
The answer in https://stackoverflow.com/a/41884661/4560833 has to be changed a little for Symfony 4:
Use ConstraintValidatorTestCase instead of AbstractConstraintValidatorTest.
Answer (b): Create the Validator inside the Unit Test (Symfony 2.0)
If you built a Constraint and a ConstraintValidator you don't need any DI container at all.
Say for example you want to test the Type constraint from Symfony and it's TypeValidator. You can simply do the following:
use Symfony\Component\Validator\Constraints\TypeValidator;
use Symfony\Component\Validator\Constraints\Type;
class TypeValidatorTest extends \PHPUnit_Framework_TestCase
{
function testIsValid()
{
// The Validator class.
$v = new TypeValidator();
// Call the isValid() method directly and pass a
// configured Type Constraint object (options
// are passed in an associative array).
$this->assertTrue($v->isValid(5, new Type(array('type' => 'integer'))));
$this->assertFalse($v->isValid(5, new Type(array('type' => 'string'))));
}
}
With this you can check every validator you like with any constraint configuration. You neither need the ValidatorFactory nor the Symfony kernel.
Update: As #psylosss pointed out, this doesn't work in Symfony 2.5. Nor does it work in Symfony >= 2.1. The interface from ConstraintValidator got changed: isValid was renamed to validate and doesn't return a boolean anymore. Now you need an ExecutionContextInterface to initialize a ConstraintValidator which itself needs at least a GlobalExecutionContextInterface and a TranslatorInterface... So basically it's not possible anymore without way too much work.
I don't see a problem with the WebTestCase. If you don't want a client, don't create one ;) But using a possibly different service than your actual application will use, that's a potential pit fall. So personally, I've done like this:
class ProductServiceTest extends Symfony\Bundle\FrameworkBundle\Test\WebTestCase
{
/**
* Setup the kernel.
*
* #return null
*/
public function setUp()
{
$kernel = self::getKernelClass();
self::$kernel = new $kernel('dev', true);
self::$kernel->boot();
}
public function testFoo(){
$em = self::$kernel->getContainer()->get('doctrine.orm.entity_manager');
$v = self::$kernel->getContainer()->get('validator');
// ...
}
}
It's less DRY than Matt answer -- as you'll repeat the code (for each test class) and boot the kernel often (for each test method), but it's self-contained and require no extra dependencies, so it depends on your needs. Plus I got rid of the static require.
Also, you're sure to have the same services that your application is using -- not default or mock, as you boot the kernel in the environnement that you wish to test.
If people still read this one in 2023, prefer to inject the ValidatorInterface for Symfony > 3 / 4.
use Symfony\Component\Validator\Validator\ValidatorInterface;
// ...
$this->validator->validate($myEntity);
Has anyone tried this?
I like moq and i like what pex is doing, but haven't tried them together. I'd prefer to use moq over moles in most cases I think but am curious to see if anyone has hit roadblocks?
Do they play nice?
Although I haven't tried, Pex and Moq should get along like old friends.
While the interception techniques between Pex and Moq are different (Pex uses the ProfilerAPI to interpret MSIL instructions; Moq uses DynamicProxy to dynamically derive classes) there are references in the Moq source code that suggest it was designed to prevent re-entrance problems where Pex would interfere with Moq.
According to the original research paper for Pex, you can decorate your code with attributes that control when the Pex rewriter is used.
From the Moq source code:
internal static MethodCall<T> Setup<T>(Mock mock, Expression<Action<T>> expression, Func<bool> condition) where T : class
{
return PexProtector.Invoke(() =>
{
var methodCall = expression.ToMethodCall();
var method = methodCall.Method;
var args = methodCall.Arguments.ToArray();
ThrowIfNotMember(expression, method);
ThrowIfCantOverride(expression, method);
var call = new MethodCall<T>(mock, condition, expression, method, args);
var targetInterceptor = GetInterceptor(methodCall.Object, mock);
targetInterceptor.AddCall(call, SetupKind.Other);
return call;
});
}
PexProtector is defined as:
internal sealed class __ProtectAttribute : Attribute
{
}
namespace Moq
{
[__Protect]
[DebuggerStepThrough]
internal static class PexProtector
{
public static void Invoke(Action action)
{
action();
}
public static T Invoke<T>(Func<T> function)
{
return function();
}
}
}
i didnt get pex amd moq to work very well toghther, allthough that was a long time ago. Pex seemed to get lost in the Reflection.Emit / dynamic proxy stuff that moq creates.
i'd suggest looking at Moles if you need to do mocking in conjunction with pex. its a pretty nice mocking framework over all and is already bundled with pex
Based on this article, I've written a custom class which implements the Watin.Core.interfaces.IFindByDefaultFactory, but I don't think I'm correctly assigning it to the watin settings, because it is never used.
Basically, Where/when should I assign to the Settings.FindByDefaultFactory? I've tried in my test Setup, and the text fixture's constructor, but neither seem to cause my custom class to be used. The tests still run and work, but I have to use the full asp.net ID's.
I'm using Watin 2.0.15.928 in VS2008 from nUnit 2.5.2.9222. I am running visual studio as administrator, and tests run sucessfully as long as I don't rely on my custom find logic.
Here's what the start of my text fixture looks like, where I set the FindByDefaultFactory
namespace Fundsmith.Web.Main.BrowserTests
{
[TestFixture]
class WatinHomepageTests
{
private IE _ie;
[SetUp]
public void Setup()
{
Settings.FindByDefaultFactory = new FindByAspIdFactory();
_ie = new IE("http://localhost/somepage.aspx");
}
//etc etc...
And this is what my custom Find By Default factory looks like (simplified), unfortunately, it's never called.
using System.Text.RegularExpressions;
using WatiN.Core;
using WatiN.Core.Constraints;
using WatiN.Core.Interfaces;
namespace Fundsmith.Web.Main.BrowserTests
{
public class FindByAspIdFactory : IFindByDefaultFactory
{
public Constraint ByDefault(string value)
{
// This code is never called :(
// My custom find by id code to cope with asp.net webforms ids...
return Find.ById(value);
}
public Constraint ByDefault(Regex value)
{
return Find.ById(value);
}
}
}
Edit: Extra information after the fact.
Based on me fuguring this out, (see answer below), It turns out that the way I was consuming Watin to find the elements was wrong. I was explicitly calling Find.ById, rather than letting the default action occur. So I'd reassigned the default but was then failing to use it!
[Test]
public void StepOneFromHomepageShouldRedirectToStepTwo()
{
_ie.TextField(Find.ById("textBoxId")).TypeText("100");
//Other test stuff...
}
Right, I've figured this one out, and it was me being an idiot and explicitly calling the Find.ById method, rather than letting the default action occur. It seems the test setup is a fine place to set the FindByDefaultFactory.
ie, I was doing this (wrong):
[Test]
public void StepOneFromHomepageShouldRedirectToStepTwo()
{
_ie.TextField(Find.ById("textBoxId")).TypeText("100");
//Other test stuff...
}
When I should have been simply doing this. (Without the explicit "Find.ById")
[Test]
public void StepOneFromHomepageShouldRedirectToStepTwo()
{
_ie.TextField("textBoxId").TypeText("100");
//Other test stuff...
}
Not only was this me being stupid, but I didn't include this in my original question, so it would have been impossible for anyone else to figure it out for certain. Double slaps for me.