I realized that I have been using setTimeout() in my project -maybe- more than I should, I did a quick research and scroll through some open source react projects on Github and decided I should ask about it.
I use setTimeout mostly for changing the classname or adding styles to animate the DOM objects also using CSS transition, one point I thought it will be hard to write unit testing with this many setTimeout.
Since I came from using AngularJS, there is a $timeoutĀ service which has the same functionality with setTimeout, but in testing you can flush the timeout like $timeout.flush() and the timeout ends instantly.
My questions;
Is there an alternative testable way that I can use instead setTimeout (logicly or programaticly)?
Is there any builtin testable function in React does the same thing with setTimeout?
Is there any react addons I can use for "flushable" timeout?
Keep in mind I'm fairly new at reactjs and haven't write any unit test on it yet.
It depends what you are using. There's a sinonjs fake timers (http://sinonjs.org/) and Jest also has this functionality (with an example): https://facebook.github.io/jest/docs/timer-mocks.html
Cheers,
Mariusz
Related
So the docs suggest using a mock store, but it's just recording all the actions and is not connected to any reducer. I basically just want to unit a test a component, and see that given an action has been dispatched, it changed- something like(in the most general way to describe):
expect(counter.props).to.equal(1)
dispatch(increment())
expect(counter.props).to.equal(2)
any ideas? thanks
There's a couple factors involved here.
First, even in normal rendering and usage, dispatching an action does not immediately update a component's props. The wrapper components generated by connect are immediately notified after the action is dispatched, but the actual re-rendering of the wrapped component generally gets batched up and queued by React. So, dispatching an action on one line will not be reflected in the props on the next line.
Second, ideally the "plain" component shouldn't actually know anything about Redux itself. It just knows that it's getting some data as props, and when an event like a button click occurs, calls some function it was given as a prop. So, testing the component should be independent from testing anything Redux-related.
If it helps, I have a whole bunch of articles on React and Redux-related testing as part of my React/Redux links list. Some of those articles might help give you some ideas.
I'm trying to write unit tests on a piece of code that imports dart:html and I ended up having a test class that's using useHtmlConfiguration();
Do I really have to do this? Because it seems everytime I run my tests, it runs in a browser, dart2js gets called and it's taking much longer than if I were testing with the dartVM. I tried it with Dartium and it also recompiles.
In fact, the only reason my code uses dart:html is because it's using HttpRequest in the package. At the end I might just end up putting an interface in front of the class doing the http request and mocking it, but I was wondering if there were an efficient way of having a good (read quick) feedback loop without having to call dart2js everytime I want to run my tests?
If your code imports dart:html the code and also tests importing this code can only be run in the browser.
I don't know why dart2js is called. You can run tests in Dartium or content_shell --dump-render-tree (headless Dartium) as Dart code without transpiling to JS first.
You might prefer using the http package which has some abstraction of HttpRequest which should on client and server (haven't tested it myself this way yet).
I'm trying to use jasmine and guard to test an ember based frontend for my rails 3.2 application. For this, I use jasminerice and guard-jasmine, phantomjs. The setup was very easy and simple and I can run some sample specs. When it comes to play with ember, things go mad. I have the spec below that test a video reader class. It should set videoHeight and videoWitdh property with the value of the corresponding video DOM element when calling loadVideo method.
When I run jasmine on my browser the test pass, but when I run it with guard and phantomjs, it fails. I got "Expect undefined to equal 640". It seems that my DOM element is not taking into account when the test run on phantomjs.
describe "VideoReader", ->
it "loads video from video DOM element", ->
videoDOM = Ember.$("<video width='640' height='480'><source src='/test.mp4'></source></video>")[0];
player = Topper.VideoReader.create();
player.loadVideo(videoDOM);
videoHeight = player.get('videoHeight');
videoWidth = player.get('videoWidth');
expect(videoHeight).toEqual(480);
expect(videoWidth).toEqual(640);
Is my spec correctly written ?
You should read the blog post about Testing in Ember.js.
I don't know what your Topper.VideoReader looks like but I guess your problem has to do with manipulating something on the DOM and not giving Ember.js a chance to propagate those changes. In your tests you should wrap your calls which interact with bindings or are manipulating the DOM in an Ember.run(function(){...}) call, as seen in the tests, for example child_views_test.js.
A summary from the discussion below:
If code you want to test interacts with the DOM, wrap it in an Ember.run call.
If you want to test for events which are fired in your code and you don't have control when exactly they are fired, use the asynchronous test features in the testing framework, like QUnit's asyncTest
I have a unit tests for Zend Framework controllers extending Zend_Test_PHPUnit_ControllerTestCase.
The tests are dispatching an action, which forwards to another action, like this:
// AdminControllerTest.php
public testAdminAction()
$this->dispath('/admin/index/index');
// forwards to login page
$this->assertModule('user');
$this->assertController('profile');
$this->assertController('login');
$this->assertResponseCode(401);
}
// NewsControllerTest.php
public testIndexAction()
{
$this->dispatch('/news/index/index');
$this->assertModule('news');
$this->assertController('index');
$this->assertController('index');
$this->assertResponseCode(200);
}
Both of the tests are passing when they are run as a seperate tests.
When I run them in the same test suite, the second one fails.
Instead dispatching /news/index/index the previous request is dispatched (user module).
How to trace this bug? Looks like I have some global state somewhere in the application, but I'm unable do debug this. How can I dump the objects between the tests in the suite? setUpBefore/AfterClass are static, so there are no so many data about the object instances.
I know this is a kind of guess what question. It's hard to provide reliable data here, because they would took to much place, so feel free to ask for details.
The whole unit test setup is more or less like described in: Testing Zend Framework MVC Applications - phly, boy, phly or Testing Zend Framework Controllers Ā« Federico Cargnelutti.
Solution:
I've determined the issue (after a little nap). The problem was not in unit test setup, but in the tested code.
I use different ACL objects based on module name. Which one to use was determined by static call to action helper, which cached the result in a private static variable to speed things up. This cache was executed only when run in a test suite. I just need more unit tests for this code :)
(I'm sorry for such a rubbish post, but I've stuck with this for a day and I hoped someone else experienced similar kind of this Heisenbug with unit tests in general)
You may try clearingrequest and response objects before dispatching each action, like this:
$this->resetRequest()
->resetResponse()
->dispatch('/news/index/index');
I am attempting add some tests to an existing QT GUI application using QTest. The GUI uses quite a bit of complicated start-up code so I'd rather not write another main() to start it again.
To me, it seems like the easiest way would be instantiate the app and then run the tests on it. I am just not sure, however what function I could plug my test object into so that I don't block the flow of messages.
I could send a special message to start the test or set a timer but that's complicated and tests are supposed to simplify things.
So where would be the best place in existing GUI to insert and qexec a Qtest object?
I'm willing to be proven wrong, but test frameworks in general (and QTest specifically from what I've used of it) tend to assume that the test framework will be driving the code to be tested, as opposed to running along side of it.
I'm also concerned about "The GUI uses quite a bit of complicated start-up code...." Are you intending on testing the startup code? Or testing other stuff around it?
Generally speaking, when I start looking at adding tests to an application, I try to find smaller pieces that are used in a lot of the application, and write tests for those. I then build up to testing the bigger pieces that integrate those smaller ones. My general idea is that if the small pieces work properly, then either I've put them together correctly and things should work, or I haven't and things should obviously fail when I try to run the application.
I should mention that there are other options for testing GUIs for Qt applications in particular. They tend to be more like scripts run on your program, with the output recorded. If that interests you, then you could look into Squish for Qt.