Unit Test Click event in typescript - unit-testing

I need to test the click events of the following code using karma jasmine. The project is of only typescript.
private createLabel() {
buttonLabel.htmlElement.onclick= () => {
-------
------
}
}
the above function creates a label and on click , it does some operation. I can able to test the creation of label, but not the click event. All examples were given for angular, not for pure typescript. Let me know any ideas to proceed further.
Version:
ts: 2.8

Related

Vue Mocha test: wrapper.setProps({}) does not update nested Components props

I am the developer of this Vue.js Plugin and am currently working on the test for v1.0.0, using already written tests for older versions with some adjustments.
Scenario
Test the components with the following structure:
// receives props and passes through
VueEllipseProgress
// receives props, adds new and passes through
EpCircleContainer
// receives props and do main SVG rendering
CircleProgress
Use Factory function:
// this is the top level VueEllipseProgress component
import Container from "../../../src/components/VueEllipseProgress.vue";
import Circle from "../../../src/components/Circle/CircleProgress.vue";
const factory = propsData => {
return mount(Container, {
propsData: {
...propsData
}
});
};
const wrapper = factory({...})
Use wrapper.setProps() in the test to apply new props. Test, how changed props affect the rendering of SVG elements on the other end. You can see the whole code on GitHub.
Problem
wrapper.setProps() updates the props of the VueEllipseProgress (top level) correctly and wrapper.vm.$props has the expected values. But the props of CircleProgress component remain unchanged, HTML still not updated. This leads to test failures.
it("do some test", () => {
/* do some test here, all is fine */
wrapper.setProps({ someProp}); // set new props
wrapper.vm.someProp; // updated
circleWrapper.vm.someProp; // still old
// fails!!!
expect(circleWrapper.element.getAttribute("someProp")).to.equal(someProp);
});
Here are more code details related to above example.
Note, that the plugin works correctly live and all props are reactive.
The test worked for earlier versions of my plugin. In the meantime i have updated #vue/cli to version 4.x.x. Maybe the failures are related to this update, but I couldn't find any information in the release notes that could confirm this.
This is not the direct solution, more a tip to avoid the problem. In my components, I use v-binde="$props" to propagate the props to subcomponents. However, this can cause issues with jsdom, like in my case.
I ended up with refactoring all my tests by testing each komponent directly, avoiding the need of nested structure and props propagation (like unit tests are supposed to be).

w2ui overlay is not rendered in cypress headless test

Test passes in headed mode, but always fails in headless mode
I am trying to perform a test on the w2ui field of type "list"
Ideally, when we click on this w2ui list element, a drop-down (overlay) is generated with the select options and then we select an option.
But while running the test in headless mode, this drop-down is not generated.
Code To reproduce the issue:-
Code for the webpage:
Link to HTML code
Save the code provided in the above link in the file "test_webpage.html". Place this HTML file in the directory where cypress.json is located.
Code of Cypress Test:
describe('W2UI List Test', function() {
it('Click List Field', function() {
cy.visit('test_webpage.html');
cy.get('.w2ui-select').siblings('.w2ui-field-helper').should('be.visible').click();
cy.wait(2000);
cy.get('#w2ui-overlay tr[index=0]').should('be.visible').click();
});
});
Test Fail ScreenShot
Yes, there is a bug in Cypress currently where certain mouse events are not properly simulated when the Test Runner window is not the active window. This is being worked on here: https://github.com/cypress-io/cypress/issues/1909#issuecomment-395995180 , This is being worked on
In the meantime, you can change your test code to this, for example:
cy.get('.w2ui-select').siblings('.w2ui-field-helper').click()
cy.contains('Barack Obama').click()
Cypressautomatically checks for actionability before clicking, so no need for should('be.visible')

Testing Gradle Plugin That Uses project.gradle.projectsEvaluated

I am trying to test a Gradle plugin that uses the BuildAdapter#ProjectsEvaluated function to allow custom configurations and dependencies to be added to my project. The problem that I'm having is that if I evaluate the project using InternalProject#evaluate in the junit test then the projectsEvaluated function is never called. If I switch to the more robust GradleRunner then I do not appear to have the ability to inspect the project(s) later to actually see if my plugin works. I have provided sample code below that shows a sample plugin and a junit test. Does anyone know how I could test this functionality?
class MyPlugin implements Plugin<Project> {
#Override
void apply(Project project) {
project.extensions.create("myPlugin", MyPluginExtension)
project.gradle.projectsEvaluated {
/*
custom logic that needs to evaluate prior
to gradle adding dependencies to project
*/
}
}
The JUnit is provided below:
class MyPluginPluginTest {
private Project project
#Before
void setup() {
project = ProjectBuilder.builder().build()
project.repositories.mavenCentral()
project.apply plugin: 'java'
project.apply plugin: MyPlugin
}
/*
Test to check whether or not the correct dependency
was added to the project when the plugin was evaluated
*/
#Test
void projectHasCheckerFrameworkDependencies() {
((ProjectInternal) project).evaluate()
Set<File> files = project.configurations.getByName('myPlugin').resolve()
assertNotEquals(0, files.size())
assertTrue(files.any { it.name.endsWith("myDependency-${project.jarName.version}.jar") })
}
}
In order to gain access to the information I required I added the projectsEvaluated closure to the projectExtensions as follows:
class MyPlugin implements Plugin<Project> {
#Override
void apply(Project project) {
project.extensions.create("myPlugin", MyPluginExtension)
def projectsEvaluatedClosure = {
/*
custom logic that needs to evaluate prior
to gradle adding dependencies to project
*/
}
project.extensions.add("myPluginProjectsEvaluatedClosure", projectsEvaluatedClosure)
project.gradle.projectsEvaluated closure
}
}
Now that the projectsEvaluated closure is accessible in the project I executed the closure manually from the test case. This isn't an ideal solution, but I was able to verify that the code was working properly.

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 with Moq, Prism 6, and Event Aggregation

I want to unit test a module by throwing messages at it via Event Aggregation to make sure it responds appropriately, either by setting properties appropriately, or by publishing other messages as a result. I am using Prism 6.
In my project, the infrastructure project has:
public class ImportantMessage : PubSubEvent<string>
{
}
ModuleA publishes a message like this:
eventAggregator.GetEvent<ImportantMessage>().Publish(importantString);
ModuleB receives the message like this:
eventAggregator.GetEvent<ImportantMessage>().Subscribe(HandleImportantMessage);
Here is HandleImportantMessage:
public void HandleImportantMessage(string importantString)
{
. . .
}
The ModuleB constructor is called as follows:
ModuleB(IEventAggregator EventAggregator)
This constructor is called by the Prism framework. For unit testing, I need to create an instance of ModuleB, and pass an IEventAggregator, probably a fake one created by Moq. And I want to do this in such a way that the message I publish carries importantString with it.
If I Google the phrase “unit tests with moq and event aggregation,” there are
several references, but I didn’t see how to use any of these approaches to pass “importantString” from ModuleA To ModuleB. The sample code for Prism 5 creates a fake event aggregator, but without using Moq. I don't understand how it works, and don't see how to pass a string with it.
My test code starts off something like this:
var moqEventAggregator = new Mock(IEventAggregator);
var moqImportantMessage = new Mock<ImportantMessage>();
moqEventAggregator.Setup(x => x.GetEvent<ImportantMessage>());
Some of the references I have seen apply something like .Returns(eventBeingListenedTo.Object);
to moqEventAggregator after Setup is applied.
I obviously need to apply .Setup(something) to moqImportantMessage in order to pass importantString, but I don't see exactly what yet.
What am I missing? How do I pass a string with the fake published message?
Basically you need to mock 2 things here:
The event aggregator
The event itself
Given you have the mock of the event you need to do as you said:
moqEventAggregator.Setup(x => x.GetEvent<ImportantMessage>()).Returns(moqImportantMessage);
Mocking the event itself should be like so:
Action<string> action;
moqImportantMessage.Setup(_ => _.Subscribe(It.IsAny<Action<string>>>()))
.Callback(_action =>
{
action = _action;
});
And then you can raise the subscription like so:
action("some string");