Jasmine spyOn with specific arguments - jasmine

Suppose I have
spyOn($cookieStore,'get').and.returnValue('abc');
This is too general for my use case. Anytime we call
$cookieStore.get('someValue') --> returns 'abc'
$cookieStore.get('anotherValue') --> returns 'abc'
I want to setup a spyOn so I get different returns based on the argument:
$cookieStore.get('someValue') --> returns 'someabc'
$cookieStore.get('anotherValue') --> returns 'anotherabc'
Any suggestions?

You can use callFake:
spyOn($cookieStore,'get').and.callFake(function(arg) {
if (arg === 'someValue'){
return 'someabc';
} else if(arg === 'anotherValue') {
return 'anotherabc';
}
});

To the ones using versions 3 and above of jasmine, you can achieve this by using a syntax similar to sinon stubs:
spyOn(componentInstance, 'myFunction')
.withArgs(myArg1).and.returnValue(myReturnObj1)
.withArgs(myArg2).and.returnValue(myReturnObj2);
details in: https://jasmine.github.io/api/edge/Spy#withArgs

One possible solution is use the expect().toHaveBeenCalledWith() to check the parameters, example:
spyOn($cookieStore,'get').and.returnValue('abc');
$cookieStore.get('someValue') --> returns 'abc';
expect($cookieStore.get).toHaveBeenCalledWith('someValue');
$cookieStore.get('anotherValue') --> returns 'abc'
expect($cookieStore.get).toHaveBeenCalledWith('anotherValue');

Another way of achieving the same result would be.... (Ideal when you are writing unit tests without using a testbed)
declare the spy in root describe block
const storageServiceSpy = jasmine.createSpyObj('StorageService',['getItem']);
and inject this spy in the place of original service in the constructor
service = new StoragePage(storageServiceSpy)
and inside the it() block...
storageServiceSpy.getItem.withArgs('data').and.callFake(() => {})

Related

What is the best way to assert that a component contains a string "case insensitive" using Cypress?

I want to assert that a component contains a string without caring about the string case.
For example, I want
cy.get('#label').should('contain.text', 'integrator');
to pass even if the label contains "Integrator."
What is the best way I can make this assertion?
You can also use cy.contains() with a regular expression
cy.contains('#label', /integrator/i) // should is implied in this command
or as an option
cy.contains('#label', 'integrator', {matchCase:false})
With should() you get retry of the expect()
cy.get('#label')
.should($el => {
expect($el.text().toLowerCase()).to.eq('integrator') // exact
// or
expect($el.text().toLowerCase()).to.contain('integrator') // partial
})
What you need is Regular expressions.
You can use the match assertion:
cy.get('#label')
.invoke('text')
.should('match', /integrator/i) //i = case sensitive
You can do like this as well:
cy.get('#label').then(($ele) => {
expect($ele.text().toLowerCase()).to.contain('integrator')
})

How to make Ruby Mocha mock only check about one parameter

I want to mock this function:
def self.set_segment_info(segment_info, history_record)
history_record.segment_info = segment_info
end
In my test, I want a mock that only confirms that I called set_segment_info with an expected value. I don't care about what I pass in for history_record.
How would I do this? I tried
SegmentHistoryRecord.expects(:set_segment_info).with(:segment_info => expected_segment_info, :history_record => anything)
But that doesn't work.
I ran into this today and ended up doing something like:
SegmentHistoryRecord.expects(:set_segment_info).with(
expected_segment_info,
anything
)
I find it more readable that the do version and it helped me avoid a rubocop issue with too many parameters.
Here's an implementation where, if your function takes a lot of parameters, it's more convenient to specify a value for just the one you care about, instead of for all of them:
expected_segment_info = # ...
SegmentHistoryRecord.expects(:set_segment_info).with() { |actual_parameters| actual_parameters[:segment_info] == expected_segment_info }
(Where, as in the original question, set_segment_info is the function being mocked, and segment_info is the parameter whose value you want to match. Note that the history_record parameter -- and any others that might be present -- don't need to be included.)
SegmentHistoryRecord.expects(:set_segment_info).with() do |param1, param2|
# change below to your verification for :segment_info
# and leave param2 doing nothing, the expectation will ignore param2
param1 == expected_segment_info
end

Spring Rest Doc junit 5 parameterized Tests support

I read the documentation, but I didn't find anything about whether the parameterized tests functionality of junit 5 is supported. I tried it but unfortunately the result is always overwritten by the next one. Does one of you know if something like the following is possible?
#ParameterizedTest
#ValueSource(strings = { "Hello", "JUnit" })
public void testSnippet(String pseudo) {
this.mockMvc.perform(get("/pseudoCode/{pseudo}", pseudo))
.andExpect(status().isOk())
.andDo(document("locations", pathParameters(
parameterWithName("pseudo").description("It's just pseudo code")
)));
}
I expecting two folders, the first with a sample containing "Hello" as path parameter and the second with "JUnit" as path parameter.
Any suggestions?
You're using the same document identifier for both test executions:
document("locations"
so... the same folder is used for both.

Nightwatch attributeContains with multiple acceptable values

I have a successful test
browser
.url(testURL)
.waitForElementPresent('body', 1000)
.verify.attributeContains('someElement', 'someAttribute', 'foo')
But for my purposes it is acceptable for 'someAttribute' to contain 'foo' OR 'bar'. I'm wondering how I can write this kind of test so that no test failures are reported by Nightwatch.
You can test if attribute contains 'foo' OR 'bar' in two steps:
get the attribute value with getAttribute() or attribute()
match a regex against the value
With getAttribute(), use regex.test():
browser.getAttribute('someElement', 'someAttribute', function(result) {
this.assert.value(/foo|bar/.test(result.value), true);
};
With attribute(), use matches() assertion:
browser.expect.element('someElement').to.have.attribute('someAttribute')
.which.matches(/foo|bar/);
use .elements() and obtain the length of element result to avoid fail message.
.elements('css selector','someElement[yourattribute="foo"]',function(result){
if(result.value.length>0){ //element exists
console.log('somelement is here')
}
else{
console.log('not here')
}
});

CaspserJS assertEval with variables

I'd like to use CasperJS to evaluate a variable equals a certain value.
I simplified my exemple as much as I could that way:
var testDate = "24/03/14";
casper.test.begin('TEST', 1, function suite(test) {
casper.start('http://www.google.com/', function() {
this.test.assertEval(function() {
return testDate == "24/03/14";
}, "testDate is 24/03/14" );
});
casper.run(function() {
this.test.done();
});
});
I don't know why it fails, here is what I get in my console:
Test file: tests.js
#TEST
FAIL testDate is 24/03/14
# type: assertEval
# file: tests.js:7
# code: }, "testDate is 24/03/14" );
# subject: null
# fn: undefined
# params: undefined
FAIL 1 test executed in 2.896s, 0 passed, 1 failed, 0 dubious, 0 skipped.
Details for the 1 failed test:
In tests.js:7
TEST
assertEval: testDate is 24/03/14
Any idea ?
UPDATE
I realised my simplified example was faulty, it didn't represent what I really needed.
Actually, what I want to achieve is to test if a variable from the current page DOM context equals a local variable.
As per manual Asserteval:
Asserts that a code evaluation in remote DOM strictly resolves to a boolean true:
your testdate variable is local to the casperjs script and is not accessible in the remote dom. You would have to inject it to the window like described here.
Ok found the answer myself.
To test if a variable from the current page DOM context equals a local variable, I realised I could use a simple assertEvalEquals():
test.assertEvalEquals(function() {
return variableFromPageDomContext;
}, localVariable);
Likewise, when testing if a variable from the current page DOM context matches a RegExp pattern, we have to use evaluate() to get the variable from the DOM as the first parameter of an assertMatch():
test.assertMatch(this.evaluate(function() {
return variableFromPageDomContext;
}), RegExpPattern);
Hope that can help.
As #Surreal answers its possible to use the assertEvalEquals() passing the function and the expected value.
However the original question wants to pass a variable from casperjs context to assertEval() function, you can simply do it as follows, passing to assertEval() three arguments: the function which receive the value, a message for the assert and the value:
var varPassToEval = 'someValue';
test.assertEval(
function(varFromCasperContext){
return varFromPageDomContext === varFromCasperContext;
},
'Assert Eval to test',
varPassToEval
);
With the above example probably is clear to use assertEvalEquals() however could be useful for more complex cases, for example imagine that you want to check if a text appears in a some <li> inside <ul> in DOM which it's dynamic and can change but you don't know at first where your text is... for this case you can use:
var somePartOfText = 'blue';
test.assertEval(
function(varFromCasperContext){
return document.getElementsByTagName("ul")[0].textContent.indexOf(varFromCasperContext) != -1;
},
'Assert Eval to test',
somePartOfText
);
Hope it helps,

Resources