In CDK testing, what is the difference between toHaveResource and toHaveResourceLike? - unit-testing

In CDK fine-grained construct tests, what is the different between
expect(...).toHaveResource(...)
and
expect(...).toHaveResourceLike(...)
from the #aws-cdk/assert/jest module?

According to the code here and here the only difference is that toHaveResource requires that values for the keys passed must match exactly, while in toHaveResourceLike actual values can be a superset of reference values. In other words, if you are trying to assert value of some property, which itself is an object, and you want to assert only subset of the object, then you should use toHaveResourceLike.
For example, let's say that you're trying to assert that your S3 bucket resource has a PublicAccessBlockConfiguration property with BlockPublicPolicy set to true.
You might write something like this:
test("has public access restricted", () => {
expect(stack).toHaveResource("AWS::S3::Bucket", {
PublicAccessBlockConfiguration: {
BlockPublicPolicy: true,
},
});
});
But this will fail because PublicAccessBlockConfiguration also has other subproperties like BlockPublicAcls. But if you switch toHaveResource here to toHaveResourceLike then it will succeed.

Related

jest-fetch-mock with classes that perform api query

All the examples of jest and jest-fetch-mock I have come across use functions that perform an API query and return a payload directly from the function call.
In my case, I have a different setup. I have a class that has a property called 'data'. In the class there is a method called "get" which pulls data using fetch API and stores it in the data property. When the method is called, it simply returns true or false based on promise resolve or reject.
I am trying to figure out how to write unit tests for this in this case. My function doesn't return the data fetched; only a boolean value.
So if I use jestSpyOn to mock the class method, how would I set the data property, and then retrieve the result?
In my code, I do something like this (NOT in testing, but in the actual app):
contactStore = new ContactListStore();
// 'all' is a sample param passed
contactStore.get('all').then(res => {
if(res){
...perform action
}
});
As you can see the res argument is only boolean, and if true, then contactStore.data will contain the information retrieved from the server.
So to run a unit test on it, I need to call a mock get, and set a mock data property.
Any ideas how this would be done?
In your mock method, you just need return true.

Scalatra multiple routes for single action

Currently i am trying to refactor a API without breaking changes. trying to migrate it from something like host:port/foo/bar to host:port/barand im wondering if in Scalatra multiple routes are supported on a single action. I am trying it like:
get("/foo/bar", "/bar") {
Ok(200)
}
its returning with a empty response on either endpoint with a response code of 0 so i'm kind of puzzled. Is this supported in Scalatra?
I know in spring it'd look something like: https://stackoverflow.com/a/5517486/4682816 but i am curious if there is something in Scalatra
Scalatra supports multiple transformers for a action, but it means the action in called if all transformers are matched. This is used to add additional conditions to the routing.
In your case, a request path can't match both "/foo/bar" and "/bar", so I guess the action is never called.
You can do it instead as follows:
get("/foo/bar"){
bar()
}
get("/bar"){
bar()
}
private def bar() = {
Ok(200)
}
or you can use regular expression:
get("^(/bar)|(/foo/bar)$".r){
Ok(200)
}

Is there a way to pass in complex arguments into Mocked Dart Services using Mockito?

I was looking at the documentation at: https://pub.dartlang.org/packages/mockito and was trying to understand it more. It seems that in the examples, the function stubs were accepting strings, but was kind of confused as to how I was going to implement my Mocked Services.
I was curious how I would do it. The services I have is pretty simple and straight forward.
class Group{}
class GroupService {}
class MockGroupService extends Mock implements GroupService {}
final mockProviders = [new Provider(MockGroupService, useExisting: GroupService];
So you can see I am using Angular dart.
I was creating a sample group in my Test file.
group("service tests", (){
MockGroupService _mock;
testBed.addProviders([mockProviders]);
setUp(() async {
fixture = await testBed.create();
_mock = new MockGroupService();
//This is where I was going to create some stubbs for the methods
when(_mock.add()).thenReturn((){
return null; //return the object.
});
//create additional when statements for edit, delete, etc.
});
});
So what i was thinking is that there would be an argument passed into add (or 2).... how would I properly code that in the when statement, and how do those 2 arguments reflect in the then statement?
Essentially, I was wanting to do a test with a complex class.. and pass it into add. Then it would just process it accordingly and return it.
Do i pass into the arguments something akin to: (using pseudocode)
when(_mock.add(argThat(hasType(Group)))).thenReturn((Group arg)=> arg);
or something similar? hasType isnt function, so im not 100% sure how to approach this design. Ideally, Im trying create the Group in the test, and then pass it into the add function accordingly. It just seems that the examples were showing Strings.
Yes mockito allows objects to be passed you can see examples in the test.
It is a bit hard to follow but you can see here that it uses deep equality to check if arguments are equal if no matchers are specified.
The second part of your question is a bit more complex. If you want to use the values that were passed into your mock as part of your response then you need to use thenAnswer. It provides you with an Invocation of what was just called. From that object you can get and return any arguments that were used in the method call.
So for your add example if you know what is being passing in and have complete access to it I would write:
Group a = new Group();
when(_mock.add(a)).thenReturn(a);
If the Group object is being created by something else I would write:
when(_mock.add(argThat(new isInstanceOf<Group>()))
.thenAnswer((invocation)=>invocation.positionalArguments[0]);
Or if you don't really care about checking for the type. Depending on what checks you are using for your test the type might already be checked for you.
when(_mock.add(any)).thenAnswer(
(invocation)=>invocation.positionalArguments[0]);
Or if you are using Dart 2.0:
when(_mock.add(typed(any))).thenAnswer(
(invocation)=>invocation.positionalArguments[0]);

Ember computed property or observer within a service

I have a service, and declare a property in the service
bucket: []
Later in the service, I add something to bucket.
I'm trying to set up in this same service an Ember computed property or observer to listen/respond to changes in bucket.
Something like:
bucketListener: Ember.computed('bucket', function() {
//do stuff in response to something being added to or removed from the bucket
}
But I can't get this to work. I've tried a lot of different permutations,using Ember.computed and Ember.observer, but I can never get bucketListener to fire.
I have checks in place and am sure that bucket is getting added to as expected or removed from as expected, but bucketListener still isn't getting called into.
Is there some trick to doing this within a service? Or am I just bungling something more basic?
To trigger computed properties, you need to use this.get('bucket').pushObject('something') instead of usual push().
When you access/use bucketListener only then computed property will be called.
Working example twiddle.https://ember-twiddle.com/776ffb2be7e129655ef62e59b2dc8697?openFiles=services.cart.js%2C
Service is no different from usual Ember.Object in terms of computed properties or observer. Please use .[] to watch for elements being added or removed and observer intead of CP to fire when property changes. You can also watch main property to be sure it will fire:
bucketListener: Ember.observer('bucket', 'bucket.[]', function() {
//do stuff in response to something being added to or removed from the bucket
}

ember computed properties executed when

I have inherited a codebase written in Ember 0.9.8.1
In some cases it can be very slow.
I'm in the process of narrowing down why it is slow.
I have noticed the following.
A function in an ArrayController is called to load data.
To load the data it gets json from the backend (fast) and then for every row it creates an (previously defined) Ember.Object (slow) and push that to the content[] of the ArrayController.
Example:
App.ExOb = Ember.Object.extend({
data1: null,
data2: null,
func1: function () { // statements }.property('data1').cacheable()
func2: function () { // statements }.property('data2').cacheable()
..etc..
})
App.lotsOfData = Ember.ArrayController.create({
content: [],
loaddata: function() {
var self=this;
get_data().forEach(function (row, index) {
var d = App.ExOb.create(row.data);
self.pushObject(d);
}
}
})
I'm trying to figure out why the creation and push of the Ember.Object is slow.
What I did notice was that on creation of the object (in the example App.ExOb.create()) every property function of the object (in the example func1() and func2()) is called.
I've tried a small bit of ember code to see why this would happen but can't seem to emulate this. The only time I can see the computed property being executed is when I do a get() of that property.
Can anyone tell me (or point me to documentation that I missed) when a computed property function is executed (other than doing a get() ofcourse :-) )?
Edit:
So far I found the following reasons to execute a computed property:
1. Calling/using the property directly
2. Using the propery in a handlebars template that is shown in the browser.
This is just a quick stab at the problem, but have you tried to create the ExOb and initialize its properties manually, something like:
self.pushObject(App.ExOb.create({
data1: row.data.data1,
data2: row.data.data2,
... etc ...
});
That might be faster, as Ember doesn't have to guess at what to copy from the row.data object and into the App.ExOb object.
Generally, the func1() and func2() functions wouldn't need to be overloaded upon object creation in my mind, but your requirements might dictate otherwise.