Jest expect().toEqual() not throwing error - unit-testing

I expected the following sample test to fail if I use toEqual(), but it passes:
it('sample test to check toEqual and toBe', () => {
const expectedAction = {test: '123', value: undefined};
const actualAction = {test: '123'};
expect(expectedAction).toEqual(actualAction);
})
The same test fails if I use .toBe(). However, if I fix the test case like this:
it('sample test to check toEqual and toBe', () => {
const expectedAction = {test: '123', value: '123'};
const actualAction = {test: '123', '123'};
expect(expectedAction).toBe(actualAction);
});
it again fails saying that "Compared values have no visual difference".
Is the behaviour correct? How to modify my test case so that it fails correctly.

If you really need it to be considered as different, one option would be to use Jest snapshot test, like:
expect(expectedAction).toMatchSnapshot();
The first time, it will create a snapshot file and print the javascript object to it, when you run the test again, it will compare it to the snapshot.
Most of the times, the snapshots are used to compare the component rendered tree, but you can use it for any javascript object.

The first one passes cause toEqual compares every element of your objects with each other, so in your case
expectedAction.test === actualAction.test
as both are '123'
but the same is true for
expectedAction.value === actualAction.value
as both are undefined
The second test fails cause toBe uses === to compare the two objects which will of cause fail as they are not the same instances. The only way that an object will passes toBe would be to use itself for comparison:
expect(expectedAction).toBe(expectedAction)

Related

Dart unit test giving inconsistent results

I have a fairly simply unit test which has been working without issue for a long time.
It has suddenly started failing.
When I run/debug the unit test in vscode the test succeeds.
When I run the test from the cli it succeeds on windows but not on linux.
dart run test -j1 test/src/functions/ask_test.dart
Which is kind of interesting as there is nothing windows/linux specific.
The test has also been working for a long time on linux.
test('ask.any - throws', () {
final validator = Ask.any([
Ask.fqdn,
Ask.ipAddress(),
Ask.inList(['localhost'])
]);
expect(
() => validator.validate('abc'),
throwsA(predicate<AskValidatorException>((e) =>
e is AskValidatorException && e.message == 'Invalid FQDN.')));
});
The test gives the following error:
Error: Expected: throws satisfies function
Actual: <Closure: () => String>
Which: threw AskValidatorException:<Invalid FQDN.>
stack package:dcli/src/functions/ask.dart 760:7 _AskValidatorAny.validate
test/src/functions/ask_test.dart 65:25 main.<fn>.<fn>
package:test_api expect
test/src/functions/ask_test.dart 64:5 main.<fn>
As you can see validate method is doing exactly what is expected (throwing).
The problem seems to be that the unit test frame work is not seeing it as a match.
This is the validator which is throwing as expected.
class _AskFQDN extends AskValidator {
const _AskFQDN();
#override
String validate(String line) {
final finalLine = line.trim().toLowerCase();
if (!isFQDN(finalLine)) {
throw AskValidatorException(red('Invalid FQDN.'));
}
return finalLine;
}
}
I'm using test 1.17.5 on Dart 2.13.
The code is from the DCli package which you can find here:
https://github.com/bsutton/dcli
The specific unit test is here
https://github.com/bsutton/dcli/blob/master/test/src/functions/ask_test.dart
I am not sure this will solve your problem, but you can make your assertion a bit cleaner if you do it like this:
expect(
() => validator.validate('abc'),
throwsA(isA<AskValidatorException>().having((e) =>
e.message == 'Invalid FQDN.')));

How to test an HTML attr doesn't exist in jest & enzyme?

I'm trying to write a test to make sure a particular attribute doesn't exist in my output html, however, I'm having trouble figuring out the appropriate way.
I'm using Jest and Enzyme.
The example html that's being tested is...
Material Design
and the lines that do the testing are...
const linkProps = component.find('a').first().props();
expect( linkProps ).not.toHaveProperty('rel');
I'm not sure if the first line is the most efficient way to find the tag, but it's confirmed to be working. The second line, however, fails even though the rel attr doesn't exist in the html.
It fails with...
expect(received).not.toHaveProperty(path)
Expected path: not "rel"
Received value: undefined
When I use toHaveProperty to test that an attribute does exist, it's fine, but what's the appropriate way to test that it doesn't exist?
I've realised that one possible answer is to use prop() and toBe()
If i'm expecting the attribute to undefined, then that's what I put into the toBe function.
const linkTag = component.find('a');
expect( linkTag.prop('rel') ).toBe(undefined);
There might be better answers though, so I'm not marking this one as correct just yet.
If your test title is 'attribute "rel" should not exist', I would follow same instructions in your test, like:
test('attribute "rel" should not exist', () => {
const linkTag = component.find('a');
expect(linkTag).not.toHaveAttribute('rel');
});
Check toHaveAttribute docs here!

Compare two values and make decision in Cypress

So I have two values on a page that I need to compare and as per the result perform some actions.
//First Block
cy.get('selctor1').invoke('text').then(somevalue => {
cy.get('selector2').should('have.text', somevalue).then(() => {
#Do Something when equal
})
})
//Second Block
cy.get('selctor1').invoke('text').then(somevalue => {
cy.get('selector2').should('not.have.text', somevalue).then(() => {
#Do Something when not equal
})
})
So for the positive case when both values are equal everything works fine. But for the case when two values are not equal, it's only checking the first block and fails. What should I do so that it executes the second block when values are not equal and not the first block?
Sorry for not being clear the first time. Here is my edited answer:
Then vs Should:
Try to avoid then where possible. then is not repeatable and will introduce unexpected behaviour.
But also will should introduce unexpeced behaviour.
Example for a bad usage of then:
describe("asd", () => {
it("fails but retries", () =>{
console.log("######### first test")
cy.wrap({ fn: () => console.log(new Date())})
.invoke("fn")
.should(r => expect(r).to.eq(true));
})
it("fails but retries not", () =>{
console.log("######### next test")
cy.wrap({ fn: () => console.log(new Date())})
.invoke("fn")
.then(r => {
expect(r).to.eq(true)
});
})
})
In this example you see the same code twice but the first block uses should while the second block uses then. The assertion must fail but in the first block, the assertion is repeated. Open the DEV COnsole to see many retries for the first block but no retry in the second.
This is what I mean by "unexpected" behaviour. Let's say, you wrap a object that is dynamically extended (maybe by a UI action) and you are expecting a property on this object. In the second block (then) the UI acton must be executed very fast and before thethenis executed so that theexpect` does not fail.
In the should case, you have 4 seconds (in case of `defaultCommandTimeout is not overwritten) left until the assert will finally fail.
Bad usage of should:
describe("ad", () => {
it("test", () => {
cy.visit("https://www.cypress.io/")
cy.get("*[aria-label='pricing']")
.invoke('text').should(someValue => {
cy.get("asdad", {timeout: 5000}).should("not.exist");
})
})
})
What would you expect? A green test? No, this test fails:
Why is this the case? Because get introduces an implicit assert "should exist" (see: https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Default-Assertions ).
Should with callback skips the default assertion (see: https://docs.cypress.io/api/commands/should.html#Notes ).I think they skip it by toggling it by flag. This could have the effect of reversing the flag again and thus forces cypress to check if "asdad" does exist even though we use should not exist.
There is an issue for this stuff: https://github.com/cypress-io/cypress/issues/5963
I do not know why cy.log has the behaviour you mentioned in your case. So either you use then if you want to use cy commands within then callback or you avoid the usage of cy commands and use should with explicit assertions (expect). Maybe after that issue is fixed, cy.log also can be used.
Old Answer:
cy.get('selctor1').invoke('text').should(someValue => {
const $el = Cypress.$('selector2');
if ($el.text() ==== someValue) {
// positive
expect()....
} else {
// negative
expect()....
}
})
You can use should with a callback. This callback (and the previous invoke command) is executed as long as the timeout is reached or no assertion fails.
You always can use the raw jQuery object to work with. This depends on whether or not you need all the checks cypress is executing during a get().
Please let me know if you need further assistance.

How to match some values of object using sinon stub

I've been writing test using sinon. During the same I wrote stub where some input parameters are passed and an object is returned. This object returns some values and a random date value generated by system at the time of execution. So need guidance on following.
How can I handle the same as the matching arguments are static in nature and I don't know the possible value of the date generated by actual code.
How can we skip certain key values of an object using sinon. i.e. say object has following values. const object = {name: "abc", employeeNumber : "123"} I only want to check if name is "abc" and don't need to match employeeNumber.
From the sinon.match docs:
Requires the value to be not null or undefined and have at least the same properties as expectation.
From the sinon.assert.match docs:
Uses sinon.match to test if the arguments can be considered a match.
Example:
test('partial object match', () => {
const object = { name: "abc", employeeNumber : "123" };
sinon.assert.match(object, { name: 'abc' }); // SUCCESS
})

RxJs 5 ascii marbles output for failing test

I am learning RxJS 5 (release candidate). I am using the ASCII marble diagrams in unit tests.
For a failing test, is there a built in function to show the actual ASCII marbles string instead of the deep equal failure result? It seems like if I have to understand and write an expected ASCII marble string that it would be useful for a failing test to show the actual ASCII marble string. It would assist in troubleshooting.
I am hoping that there is a built in function that is effectively the reverse of parseMarbles(). I have not found anything yet when searching through the documentation and source code.
Below is an example taken from Writing marble tests - anatomy of a test that I modified to get a failing test. It gives the following output:
AssertionError: expected [ Array(5) ] to deeply equal [ Array(4) ]Error
I would rather see something like:
AssertionError: expected "'---(be)----c-f-----|'"
to equal "'---(be)----c-------|'"
http://jsbin.com/hipepew/edit?js,output
mocha.setup('bdd');
const expect = chai.expect;
describe('RXJS 5 Marbles', () => {
it("basic anatomy of a failing test", () => {
const rxTestScheduler: TestScheduler = new Rx.TestScheduler(function (actual, expected) {
expect(actual).to.deep.equal(expected);
});
const e1 = rxTestScheduler.createHotObservable<string>('----a--^--b-------c--|');
const e2 = rxTestScheduler.createHotObservable<string>('---d-^--e---------f-----|');
const expectedFail = '---(be)----c-------|';//missing f at frame 130
rxTestScheduler.expectObservable(e1.merge(e2)).toBe(expectedFail);
rxTestScheduler.flush();
});
});
mocha.run();