Stack trace for Jasmine test with the Resharper 7 test runner - unit-testing

How do you get the Resharper 7 test runner to show the stacktrace for Jasmine tests.
My setup is Resharper 7 (build in Jasmine) testrunner and PhantomJs. When executing any failing test the error message always ends with:
Exception doesn't have a stacktrace
In the 1.6 "Lavender" version of Phantom has added the feature to print the stacktrace when an error occurs.
To replicate this just create a mytest.js file and add the following code to it:
describe("A suite", function() {
it("contains spec with an expectation", function() {
expect(true).toBe(false);
});
});

Sorry, I don't use Resharper, but I used to face the same issue with phantomjs and jasmine ConsoleReporter.
I think it boils down to the fact that jasmine does not throw an Error message for failed expectations and that the stack is captured by phantomjs only when error is actually thrown (jasmine.js):
jasmine.ExpectationResult = function(params) {
...
var trace = (params.trace || new Error(this.message));
};
Changing that line as follows fixed it for me:
var err;
try { throw new Error(this.message); } catch(e) { err = e };
var trace = (params.trace || err);

In the spec file, where you have your javascript (jasmine) unit tests, you need a reference to the source that is being tested.
Normally you have this in the SpecRunner.html, but Resharper rolls it's own SpecRunner.
Add this reference line to the top of the XyzSpec.js file
/// <reference path="/js/path-goes-here/your-file-here.js" />
describe("Utils", function () {
describe("when calculating quantity", function() {
...
Drove me almost nuts until I started looking around in Resharper's spec runner.
PS: If a new problem shows up 'Unit Test Runner failed to load test assembly' and you have Chrome as default browser, change the browser for javascript unit tests in the Resharper options.

Got a good response from the Jetbrains Resharper team when I logged the issue. They fixed it and it's in the 7.1 release of Resharper, which can be downloaded from their EAP site

Related

ReSharper not supporting Assert.That

I'm in the process of returning to ReSharper recently, using trial of the newest version - 2022.2.3. I've got quite surprised when one of my nUnit tests failed in a weird way, when run by Resharper's built in Unit Test runner. Something that has never happened to me with a Test Explorer.
As long as the Asserts pass, it's all fine - green, all tests are listed. However, when the assert fails, it says One or more child tests had errors. Exception doesn't have a stacktrace
Not only there is no mention of actual values that weren't correct, but the whole failing test seems to be gone!
This happens only when I use the 'modern' approach with Assert.That. So
Assert.That(httpContext.Response.StatusCode, Is.EqualTo(200));
is causing issues, meanwhile, the more classic:
Assert.AreEqual(200, httpContext.Response.StatusCode);
works as expected. Is that something that is a known bug, or maybe some attributes are required? JetBrains claims they have full support of nUnit out of the box, so that is a bit surprising.
NOTE: the tests methods are async, awaiting result and returning Tasks, beside this nothing unusual.
EDIT: The test code is as follows, ApiKeyMiddleware is any middleware that returns response with 200 here.
[TestFixture]
public class ApiKeyMiddlewareTests
{
[Test]
public async Task Invoke_ActiveKey_Authorized()
{
var httpContext = new DefaultHttpContext();
httpContext.Request.Headers.Add("XXXXX", "xxxx");
var configuration = Options.Create(new AccessConfiguration { ActiveApiKeys = new List<string> { "xxxx" } });
var middleware = new ApiKeyMiddleware(GetEmptyRequest(), configuration);
await middleware.Invoke(httpContext);
Assert.That(httpContext.Response.StatusCode, Is.EqualTo(200)); //change to anything else than 200 and it fails + vanishes
}
}

Unit test a polymer web component that uses firebase

I have been trying to configure offline unit tests for polymer web components that use the latest release of Firebase distributed database. Some of my tests are passing, but others—that look nigh identical to passing ones—are not running properly.
I have set up a project on github that demonstrates my configuration, and I'll provide some more commentary below.
Sample:
https://github.com/doctor-g/wct-firebase-demo
In that project, there are two suites of tests that work fine. The simplest is offline-test, which doesn't use web components at all. It simply shows that it's possible to use the firebase database's offline mode to run some unit tests. The heart of this trick is the in the suiteSetup method shown below—a trick I picked up from nfarina's work on firebase-server.
suiteSetup(function() {
app = firebase.initializeApp({
apiKey: 'fake',
authDomain: 'fake',
databaseURL: 'https://fakeserver.firebaseio.com',
storageBucket: 'fake'
});
db = app.database();
db.goOffline();
});
All the tests in offline-test pass.
The next suite is wct-firebase-demo-app_test.html, which test the eponymous web component. This suite contains a series of unit tests that are set up like offline-test and that pass. Following the idea of dependency injection, the wct-firebase-demo-app component has a database attribute into which is passed the firebase database reference, and this is used to make all the firebase calls. Here's an example from the suite:
test('offline set string from web component attribute', function(done) {
element.database = db;
element.database.ref('foo').set('bar');
element.database.ref('foo').once('value', function(snapshot) {
assert.equal(snapshot.val(), 'bar');
done();
});
});
I have some very simple methods in the component as well, in my attempt to triangulate toward the broken pieces I'll talk about in a moment. Suffice it to say that this test passes:
test('offline push string from web component function', function(done) {
element.database = db;
let resultRef = element.pushIt('foo', 'bar');
element.database.ref('foo').once('value', function(snapshot) {
assert.equal(snapshot.val()[resultRef.key], 'bar');
done();
});
});
and is backed by this implementation in wct-firebase-demo-app:
pushIt: function(at, value) {
return this.database.ref(at).push(value);
},
Once again, these all pass. Now we get to the real quandary. There's a suite of tests for another element, x-element, which has a method pushData:
pushData: function(at, data) {
this.database.ref(at).push(data);
}
The test for this method is the only test in its suite:
test('pushData has an effect', function(done) {
element.database = db;
element.pushData('foo', 'xyz');
db.ref('foo').once('value', function(snapshot) {
expect(snapshot.val()).not.to.be.empty;
done();
});
});
This test does not pass. While this test is running, the console comes up with an error message:
Your API key is invalid, please check you have copied it correctly.
By setting some breakpoints and walking through the execution, it seems to me that this error comes up after the call to once but before the callback is triggered. Note, again, this doesn't happen with the same test structure described above that's in wct-firebase-demo-app.
That's where I'm stuck. Why do offline-test and wct-firebase-demo-app_test suites work fine, but I get this API key error in x-element_test? The only other clue I have is that if I copy in a valid API key into my initializeApp configuration, then I get a test timeout instead.
UPDATE:
Here is a (patched-together) image of my console log when running the tests.:
To illustrate the issue brought up by tony19 below, here's the console log with just pushData has an effect in x-element_test commented out:
The offline-test results are apparently false positives. If you check the Chrome console, offline-test actually throws the same error:
The error doesn't affect the test results most likely because the API key validation occurs asynchronously after the test has already completed. If you could somehow hook into that validation, you'd be able to to catch the error in your tests.
Commenting out all tests except for offline firebase is ok shows the error still occurring, which points to suiteSetup(). Narrowing the problem down further by commenting 2 of the 3 function calls in the setup, we'll see the error is caused by the call to firebase.initializeApp() (and not necessarily related to once() as you had suspected).
One workaround to consider is wrapping the Firebase library in a class/interface, and mocking that for unit tests.

Unit Testing in Nancy causing Routebuilder exception using TinyIoc

Getting a System.MissingMethodException, Method not found: 'Void RouteBuilder.set_Item()
Get["/foo"] = parameters => { return Bar(Request);};
This runs fine when calling from browser, but fails when testing with this setup
var browser = new Browser(with =>
{
with.Module<Foobar>();
}
var response = brower.Get("/Foo", with => {with.HttpRequest();});
Any clue why the Routebuilder for testing won't pick up this route?
Turns out I had created the test project using the pre-release version of Nancy.Testing. This in turn made TinyIOC unhappy when trying to build routes/dependencies. So, if you see this mysterious message, check that your working code and test code are referencing the same packages.

Karma + Jasmine reporting 0 tests run when there are tests

I'm trying to run some Jasmine tests in Karma but the tests are failing because it's saying that it ran 0 of 0 tests. Can someone tell me what I'm doing wrong?
The async request mock fires and hits the callback. Even when I go to the debugger, it says 2 tests completed in the debugger, but failing in the console. What gives?
describe('User Info Tests:', function () {
describe('Fetch User Info:', function () {
it("User Name should match", function(done) {
// mock async request
getUserProfile(1, 2, function (userProfile) {
var match = userProfile.displayName === 'Unit Test User';
expect(match).toBeTruthy();
done();
}, function (msg) {
done();
throw msg;
}); 
});
});
});
See the screenshot below of the debug console of the tests running. You will see the tests ran with a status of SUCCESS.
So the problem was I wasn't including the karam-requirejs plugin in the karam.conf.js file. Apparently it doesn't want you to include your own copy of require.js in the files collection. Once I added that plugin in, everything just worked.
frameworks: ['jasmine-jquery', 'jasmine', 'requirejs'],
plugins: [
'karma-phantomjs-launcher',
'karma-chrome-launcher',
'karma-jasmine-jquery',
'karma-jasmine',
'karma-requirejs'
],
Make sure the karma-requirejs plugin is actually installed through npm and in your package.json as well!

Anyone have a working Jasmine unittest that runs in Resharper 7 EAP?

I'd really like to be using the R#r test running for my javascript unittests. R#r 7 EAP recognizes the tests but when I launch them the runner shows '... Test wasn't run' for all tests.
I can't find any info on what the R#r test runner expects in terms of configuration/directory structure.
Directory structure and sample test posted here
A basic/hardcoded jasmin unit test does work under R#r 7 EAP. This implies that jasmine is baked in to R#r i guess. Have an open question regarding same.
describe('resharper jasmine testrunner', function () {
describe('simplest possible test', function () {
it('should execute', function() {
expect(true).toBe(true);
});
});
});
Got a pointer on the R#r forum that doc comment references are your 'includes' (or jsTestDriver.conf equiv).
/// <reference path="../../libs/testing/jasmine/jasmine.js"/>
/// <reference path="../../libs/crunch/jquery-1.6.2.js"/>
Have yet to get my real tests passing though the now run. Investigating fixture paths next.
I'm not sure how advanced of a solution/structure you're looking for, as I just started looking into this myself, but i have a simple example test "working"*... (using Resharper 7 EAP 7.0.56.103). As far as i know, you can structure your test files anyway/where you want, as long as you include references to all of its dependencies with <reference path="foo/path/file.js" />)
*These pass inside the ReSharper unit tests session window. The browser does not show me any sort of test info but rather a blank screen with some jasmine-related html in the source.
/scripts/cheese.js
function Cheese() {
return {
isGood: true
};
}
/tests/cheeseTest.js
/// <reference path="/scripts/cheese.js"/>
describe('simplest possible test', function() {
var cheese = null;
it('cheese is good', function() {
cheese = new Cheese();
expect(cheese.isGood).toBe(true);
});
});