func.scss:
#import './variables.scss';
#function r($px, $isFixed: true) {
#if $px != 0 {
#return if($isFixed, $px / $ratio + 0.01, $px / $ratio) / $browser-default-font-size * 1rem;
} #else {
#return 0;
}
}
How to write unit tests for SCSS function? And it provides assertion, mock, stub functions like jestjs or sinonjs. So that I can mock the #import scss module and its functions, variables($browser-default-font-size) and so on.
Related
I am trying to unit test some code that looks like this
fun doSomething() {
val someObject: SomeObject?
if (someObject != null) {
val file: File = File(someObject.path)
if (file.exists()) {
// Do some stuff 1.1
} else {
// Do some stuff 1.2
}
} else {
// Some some stuff 2
}
}
I want to test for the time where someObject is not null, and file.exists == true. I am trying to mock this with mockito, because I do not need the file to actually exist during my test. The logic around it is more important to me. Is it possible to do something like this?
whenever(type(File::class.java).exists()).thenReturn(true)
so that any file during the test will always resolve to true when checking if it exists or not?
I'm about to start learning spock and I'm trying some basic stuff.
I want to check File's: exist() and getText() functionality
So I wrote the following test:
class MyTestSpec extends Specification {
def "test file"() {
given:
def mockFile = Mock(File,constructorArgs :["./doesNotExist.txt"])
mockFile.exists() >> true
mockFile.getText() >> "sampleText"
when:
def res = ""
if(mockFile.exists()) {
res = mockFile.getText()
}
then:
"sampleText" == res
1 * mockFile.exists()
1 * mockFile.getText()
}
}
This fails on:
Too few invocations for:
1 * mockFile.getText() (0 invocations)
Unmatched invocations (ordered by similarity):
None
When I comment the 'verifications' in 'then' block, I get:
java.lang.NullPointerException at
java.io.FileInputStream.(FileInputStream.java:138) at
groovy.util.CharsetToolkit.(CharsetToolkit.java:69) at
MyTestSpec.Test Existing Resource(MyTestSpec.groovy:83)
So my question is: How Exactly I can organize my test? Why does it assume that getText should not be called?
I'm using groovy 2.4 and spock 1.0
The solution will be:
#Grab('org.spockframework:spock-core:0.7-groovy-2.0')
#Grab('cglib:cglib:3.1')
#Grab('org.ow2.asm:asm-all:5.0.3')
import spock.lang.*
class MyTestSpec extends Specification {
def "test file"() {
given:
def mockFile = GroovyMock(File, constructorArgs :["./doesNotExist.txt"])
when:
def res = ""
if(mockFile.exists()) {
res = mockFile.getText()
}
then:
"sampleText" == res
1 * mockFile.exists() >> true
1 * mockFile.getText() >> "sampleText"
}
}
On of the problems is creating a mock. Because of a dynamic nature of groovy some functionality - e.g. getText() method for File class - is added at runtime. It requires mocks to be constructed in a different way. Have a look at spock mock implementation enum and extract:
An implementation specifically targeting Groovy callers. Supports mocking of dynamic methods, constructors, static methods, and "magic" mocking of all objects of a particular type.
The second problem is defining mock behavior and verifying the interactions. When you both mock and stub it must happen in the same interaction (here, in then block), here is he relevant part of the docs.
I'd like to unit test some logic in my directive :
...
link: function ($scope, $element) {
var rightMargin = 3;
var w = $element.find('span')[0].scrollWidth;
if (w > 100) {
$element.css('width', (w + rightMargin) + 'px');
}
...
Because the $compile service doesn't really add elements on document, scrollWidth always returns 0.
So I don't know how to stub the returned value of $element.find call because there is no way to access $element instance in my unit test.
Try setting the HTML of the page directly inside of body
Using innerHTML:
angular.element(document.body).html('<div class="my-elm" my-directive></div>');
var elm = angular.element(document.body.querySelector('.my-elm'));
$compile(elm)($rootScope);
Or using append:
var elm = angular.element('<div class="my-elm" my-directive></div>');
angular.element(document.body).append(elm);
$compile(elm)($rootScope);
If this is a unit test, then you shouldn't be testing the external dependencies, only that you're logic is accurate. I'd stub it out like.
spyOn($element,'css');
#call your code here
expect($element.css).toHaveBeenCalledWith('width','99px');
In a grails 2 project I'm using groovy's metaclass programming to add some methods to my domain classes.
Everything is working fine at runtime and I can run my integration tests fine.
But for unit tests I have some issues.
I have created a test mixin that is in charge of initializing the metaclass programming part.
This mixin is not running reliably:
the methods added to the metaclass are not available, or they are available after a first call, or they are available only after a previous grails test-app unit: command has been called.
This is quite a problem for continuous build.
You should be able to reproduce this issue (at least with grails 2.0.4) by
0) create a new grails projects
1) add a domain object
create-domain-class playground.Data
2) add this class to your src/groovy/playground dir
package playground
import grails.test.mixin.domain.DomainClassUnitTestMixin
import grails.test.mixin.support.GrailsUnitTestMixin
import org.codehaus.groovy.grails.commons.GrailsApplication
import org.codehaus.groovy.grails.commons.GrailsDomainClass
import org.junit.Before
class EnhanceDomainTestMixin {
boolean enhancerMethodCalled = false;
GrailsApplication application
MetaMethod mockDomainMethod
//replace the mockDomain Method from DomainClassUnitTestMixin with this closure
def enhancedMockDomain = { Class cl, List list ->
def enhanced =cl.metaClass.getMetaMethod("isEnhanced")
try {
//run the mockDomain method to have the mocked domain class registered in the grails application
mockDomainMethod.invoke(delegate, cl, list)
}
finally {
//enhance the grails domain with a new method
def domain = application.getDomainClass(cl.name) as GrailsDomainClass
domain.metaClass.isEnhanced = { return true; }
assert domain.newInstance().isEnhanced();
}
}
#Before void runDomainEnhancer() {
enhancerMethodCalled = true;
//GrailsUnitTestMixin.initGrailsApplication() should have already been called. (at least this was not an issue here)
application = GrailsUnitTestMixin.grailsApplication
//pick the mockDomain method
mockDomainMethod = DomainClassUnitTestMixin.metaClass.pickMethod("mockDomain", Class, List)
//if the picked mockDomain has never been enhanced, wrap it.
if(mockDomainMethod != enhancedMockDomain) {
DomainClassUnitTestMixin.metaClass.mockDomain = enhancedMockDomain
}
}
}
3) Add this small utils class (in test/unit/playground)
package playground
class TestSetup {
static Data d1
static void setup() {
d1 = new Data()
assert d1.isEnhanced()
}
}
4) Add these tests into the unit test already created by grails DataTests
package playground
import grails.test.mixin.*
#TestFor(Data)
#TestMixin(EnhanceDomainTestMixin)
class DataTests {
void testIsEnhancedLocal() {
assert enhancerMethodCalled
Data d = new Data()
assert d.isEnhanced()
}
void testIsEnhancedLocalSecondTime() {
assert enhancerMethodCalled
Data d = new Data()
assert d.isEnhanced()
}
void testIsEnhancedGlobalFirstTime() {
assert enhancerMethodCalled
TestSetup.setup()
assert TestSetup.d1 != null
}
void testIsEnhancedGlobalSecondTime() {
assert enhancerMethodCalled
TestSetup.setup()
assert TestSetup.d1 != null
}
}
Now run this command:
grails test-app unit:
you should have something like this output:
| Completed 4 unit tests, 4 failed in 1651ms
| Tests FAILED - view reports in target\test-reports
Now run the this command again (sometime one more is needed):
grails test-app unit: playground.DataTests
testMixin> grails test-app unit: playground.DataTests
| Completed 4 unit tests, 0 failed in 1384ms
| Tests PASSED - view reports in target\test-reports
So does anyone has a clue of why the metaClass modification is not reliable while running unit tests ? And how to workaround this issue ?
I had to use grailsApplication config in my domain class method. I ran into the same problem. Try using Holders.config instead of grailsApplication.config. It worked for me.
What's a good way to profile doctrine queries when Doctrine 2.0 has been integrated into codeigniter?
Using the usual CI profiler does not how the queries executed because it's using Doctrine and not the native, active record.
e.g. when you add this code $this->output->enable_profiler(TRUE); it should also show the queries executed.
http://codeigniter.com/user_guide/general/profiling.html
You can add a profiler in the doctrine package
namespace Doctrine\DBAL\Logging;
class Profiler implements SQLLogger
{
public $start = null;
private $ci;
public function __construct()
{
$this->ci =& get_instance();
}
/**
* {#inheritdoc}
*/
public function startQuery($sql, array $params = null, array $types = null)
{
$this->start = microtime(true);
$this->ci->db->queries[] = "/* doctrine */ \n".$sql;
}
/**
* {#inheritdoc}
*/
public function stopQuery()
{
$this->ci->db->query_times[] = microtime(true) - $this->start;
}
}
Then load the profiler as a logger in your main doctrine library (doctrine.php for me)
$logger = new \Doctrine\DBAL\Logging\Profiler;
$config->setSQLLogger($logger);
And the normal profiling will work fine.
Compatible with CodeIgniter..
https://github.com/ahmetkapikiran/CodeIgniter-Doctrine-Profiler