-
Notifications
You must be signed in to change notification settings - Fork 455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unit testing - toHaveResource() - found no resources instead #1850
Comments
While we seem to have answered the question I'd like to keep this issue open and add a proper warning / error if someone passes a stack into synthScope. |
If not too difficult, actually just allowing a stack would be more user friendly. |
Can you folks help understand the solution here? If I pass in a This is how I've modified the above example – import "cdktf/lib/testing/adapters/jest";
import { Testing } from "cdktf";
+import { Construct } from "constructs";
import { PortalStack } from "../main";
import { Application } from "@cdktf/provider-azuread";
+ class PortalConstruct extends Construct {
+ constructor(scope: Construct, options: Record<PropertyKey, unknown>) {
+ super(scope, `${options.environment}-construct`)
+ new PortalStack(scope, environment)
+ }
+}
describe("Configuration", () => {
it("should contain an application", () => {
expect(
Testing.synthScope((scope) => {
+ new PortalConstruct(scope, 'test');
- new PortalStack(scope, 'test');
})
).toHaveResource(Application);
});
}); |
This is because your construct contains a stack. A stack does not synthesize into JSON like a construct would, but it writes a file to disk with it's childrens JSON in it. This hides the content from the testing marchers. You should abstract the things you do in a stack in one or more constructs and test how they work together here |
Running into the same issue. Is there any complete example that can be posted by the team to make it easier for users who run into this issue with testing? thanks! |
Hopefully this helps. There are also internal tests of the testing framework now (for example: https://github.com/hashicorp/terraform-cdk/tree/main/test/python/testing-matchers) |
@jsteinich Thanks, that does help a bit, although it could use some more clarity –
Additionally, not all of us use Jest, even though it is the most popular testing framework. For folks that use other frameworks, it would help if there was an example that shows how to use import tap from 'tap'
import expect from 'expect'
import { Testing, testingMatchers } from 'cdktf'
import { MyConstruct } from '../main'
import { Record as CFDNSRecord } from '../.gen/providers/cloudflare'
import type { TerraformConstructor } from 'cdktf/lib/testing/matchers'
tap.Test.prototype.addAssert(
'toHaveResource',
3,
// NOTE: has to be a regular function and not an arrow function
// for the `this` binding to work correctly.
function toHaveResource(
hcl: string,
message: string,
resource: {
ctor: TerraformConstructor
props: Record<string, string>
},
) {
const msg = message || 'Terraform stack is missing property'
const toHaveResourceWithProperties =
testingMatchers.getToHaveResourceWithProperties(
(items: Array<string>, assertedProperties: Record<string, unknown>) => {
if (Object.entries(assertedProperties).length === 0) {
return items.length > 0
}
return expect
.arrayContaining([expect.objectContaining(assertedProperties)])
.asymmetricMatch(items)
},
)
const self = this as unknown as typeof tap
return self.ok(
toHaveResourceWithProperties(hcl, resource.ctor, resource.props).pass,
msg,
resource,
)
},
)
void tap.test('infra > should include all resources', (t) => {
t.plan(1)
const hclJson = Testing.synthScope((scope) => {
new MyConstruct(scope)
})
t.toHaveResource(hclJson, 'should have the Cloudflare DNS record', {
ctor: CFDNSRecord,
props: { type: 'CNAME' },
})
t.end()
}) |
https://www.terraform.io/cdktf/concepts/constructs has some more information on constructs, including an example and a comparison to stacks.
That's great. You can also use the |
I just ran across this issue. I used Then I ran into Ran into this issue from a search. I didn't see anything from docs I came across of the need to use Seems As a new user the docs and generated code don't seem to talk about this issue ... and would be nice if initial setup worked more out of the box. |
I've read all the links here and I'm still confused about what a it("should contain a container", () => {
const stack = new OnPremStack(Testing.app(), "learn-cdktf-docker");
const synthesized = Testing.synth(stack);
expect(synthesized).toHaveResource(Container);
}); |
Hey @iot-resister!
Hard to say exactly what the issue is from the snippet you've provided, could you provide a bit more context on what |
Same problem here: it("check if this can be planned", () => {
const app: App = Testing.app();
const stack: TerraformStack = new TerraformStack(app, "test");
expect(Testing.fullSynth(stack)).toPlanSuccessfully();
}); This outputs:
|
After change the package versions, it back working correctly. Follow the versions:
|
Community Note
cdktf & Language Versions
cdktf 0.11.0 (type-script)
Affected Resource(s)
Unit tests not working like I would expect. Could be me though :)
Debug Output
N/A
Expected Behavior
Test should pass unless I'm doing something wrong.
Actual Behavior
Steps to Reproduce
Important Factoids
cdktf synth/diff/deploy
work perfectly finecdk.tf.json
undercdktf.out
contains the following:References (main.ts)
The text was updated successfully, but these errors were encountered: