Skip to content
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

Breaking Change with AwsStub v 2.2.0 through the introduction of the TConfiguration type #167

Closed
1 task done
nikimicallef opened this issue Jun 28, 2023 · 6 comments
Closed
1 task done
Labels
bug Something isn't working

Comments

@nikimicallef
Copy link

Checklist

  • I have read Caveats documentation and didn't find a solution for this problem there.

Bug description

V2.2.0 changes the required types for the AwsStub through the introduction of the TConfiguration type. However, it is not clear to me what I need to set there. The only part I found in the documentation regarding this parameter is the following

Without any configuration, Client#send() invocation returns undefined.

Can we get a bit more information of what is meant to be set for this type parameter please?

Reproduction

s3Client: AwsStub<ServiceInputTypes, ServiceOutputTypes>,

Environment

  • Node version: 18.12.1
  • Testing lib and version: jest 29.5.0
  • Typescript version:
  • AWS SDK v3 Client mock version: 2.2.0
  • AWS JS SDK libs and versions:
    • "@aws-sdk/client-dynamodb": "3.359.0"
    • "@aws-sdk/client-s3": "3.359.0"
    • "@aws-sdk/client-sqs": "3.359.0"
    • "@aws-sdk/util-dynamodb": "3.359.0"
@nikimicallef nikimicallef added the bug Something isn't working label Jun 28, 2023
@m-radzikowski
Copy link
Owner

Hey, sorry for that. AwsStub, while publicly exposed, was not intended to be used directly. Instead, you should use AwsClientStub type:

let snsMock: AwsClientStub<SNSClient>;
snsMock = mockClient(SNSClient);

Although I know that's not mentioned in the README. I will improve the docs regarding this.

Please let me know if that solves your issue.

@nikimicallef
Copy link
Author

nikimicallef commented Jun 28, 2023

I've tried a few more things but we still have the same issue. Maybe I can provide more context.

We have something similar to the following

import {AwsStub, mockClient} from 'aws-sdk-client-mock';
import {S3Client} from '@aws-sdk/client-s3';

function fun(s3Client: AwsStub<ServiceInputTypes, ServiceOutputTypes>) { ... }
const s3Client = mockClient(S3Client);
fun(s3Client);

This obviously breaks since the AwsStub now requires a 3rd parameter. Based on your feedback, I tried the following.

import {AwsClientStub, mockClient} from 'aws-sdk-client-mock';
import {S3Client} from '@aws-sdk/client-s3';

function fun(s3Client: AwsClientStub<S3Client>) { ... }
const s3Client = mockClient(S3Client);
fun(s3Client);

This returns the following on runtime

Argument of type 'AwsStub<ServiceInputTypes, ServiceOutputTypes, SmithyResolvedConfiguration<HttpHandlerOptions>>' is not assignable to parameter of type 'AwsStub<ServiceInputTypes, ServiceOutputTypes, S3ClientResolvedConfig>'.
      Type 'SmithyResolvedConfiguration<HttpHandlerOptions>' is not assignable to type 'S3ClientResolvedConfig'.
        Type 'SmithyConfiguration<HttpHandlerOptions>' is missing the following properties from type 'Required<ClientDefaults>': sha256, urlParser, bodyLengthChecker, streamCollector, and 24 more.

    28         fun(s3Client, expectedRetentionUntil);

This seems to be because the type returned by the mockClient is AwsStub<ServiceInputTypes, ServiceOutputTypes, S3ClientResolvedConfig> while the AwsClientStub<S3Client> is of type AwsStub<ServiceInputTypes, ServiceOutputTypes, SmithyResolvedConfiguration<HttpHandlerOptions>>. I'm not sure if it is also the case for the SNS Client, as per your example, but we are using both the S3 Client and the Dynamo DB Client and both have the same issue.

A temporary solution is to leave my original code and set the 3rd parameter to any but that is not a 'real' solution imo.

@m-radzikowski
Copy link
Owner

Just to let you know I'm looking into that:

  1. Yes, it should work with AwsClientStub<S3Client> like you posted in the example.
  2. But it throws type error if tsconfig options are set with strict=true or strictFunctionTypes=true. Weirdly, if you change strictFunctionTypes to false (or strict=false, which implies the other), error disappears. I would expect the opposite.
  3. With strictFunctionTypes=true the mockClient() output type is AwsStub<ServiceInputTypes, ServiceOutputTypes, S3ClientResolvedConfig> and it conforms to the AwsClientStub<S3Client> type.
  4. With strictFunctionTypes=false the output type is AwsStub<ServiceInputTypes, ServiceOutputTypes, SmithyResolvedConfiguration<HttpHandlerOptions>> - seems like TS makes few jumps and resolves to a different type

Ideally, the mockClient() should return AwsClientStub<> type like it's declared, but it does not. Instead, it hops again and returns AwsStub directly. This makes types in library unit tests slightly different from when library is built, which originally made me unaware of this and let this problem pass tests.

While I agree this is an unexpected breaking change, releasing a patch with a rollback would cause more chaos. Especially that AwsStub type is probably not used in most cases.

The workaround, for now, is to use AwsStub<ServiceInputTypes, ServiceOutputTypes, any> or, if you have strict=true or strictFunctionTypes=true in tsconfig, AwsClientStub<S3Client>. Meanwhile, I will try to fix the types.

@m-radzikowski
Copy link
Owner

After spending another evening on this, my recommendation is to:

  • set tsconfig option strict=true or at least strictFunctionTypes=true
  • and use AwsClientStub<S3Client> type for the mockClient() result.

I can't get rid of type errors between AwsClientStub type and AwsStub class with strictFunctionTypes=false.

I'm leaving this open, but I don't plan anything better soon simply because I have no further ideas at the moment.

@nikimicallef
Copy link
Author

Thank you for your effort on this issue. I think leaving it open with the suggested solution is a decent enough 'conclusion'. Thank you :)

@ArmenOzcelik
Copy link

Hi,

I had the same issue when upgrading to "@aws-sdk/client-s3": "3.369.0" and "aws-sdk-client-mock": "3.0.0".
As you suggested, adding strictFunctionTypes: true in tsconfig file resolved the issue without breaking something else.

This thread saved me a lot of time, thanks to both of you!

TomJKing added a commit to nationalarchives/tdr-transfer-frontend that referenced this issue Jul 13, 2023
Following solution outlined in this thread: m-radzikowski/aws-sdk-client-mock#167

Does not appear to cause any further issues with the Typescript
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants