用玩笑嘲笑React-Redux存储

时间:2020-08-14 19:22:32

标签: reactjs redux jestjs

我们的React-Redux应用程序使用create-react-app。我们正在尝试将Jest / Enzyme / redux-mock-store应用于大型代码库。我们的src / store.js文件是标准的react-redux脚本,用于运行reducers并构造初始状态。这个src / store.js是解决问题的关键。

问题是,当我们开始进行jest测试运行时,jest加载src / store.js 7次,然后(大约)为每个测试加载一次。 我必须抑制这种情况,并且不知道如何解决。我必须抑制的原因是,它始终使商店处于初始状态,并且有一个关键的AppConfig属性在该商店中,必须填充该商店,以防止因开玩笑而停止的javascript错误。我已经有一个函数,该函数返回模拟存储以供提供程序使用。那很好。但是我们的组件会从Constructor(),componentDidMount()等调用到api函数。这些api函数看不到从Provider删除的状态。相反,api函数会执行以下操作:

    // AppConfig is an immutable Map 
    const { AppConfig } = store.getState();
    const stuff = AppConfig.get(‘stuff’).toJS();

这是一个JS错误,因为AppConfig为空,并且toJS()在未定义时被调用。 (这在运行时永远不会成为问题,因为在没有准备好AppConfg的情况下我们不构造任何组件。)有两种解决方案,涉及到重构我可以做的App。但我宁愿弄清楚如何正确地使用玩笑。我该如何提供模拟redux状态而又不会因玩笑的src / store.js重复加载而使它瘫痪?

这真杀了我。在Jest,create-react-app或???中是什么?启动这些不必要的src / store.js负载?如何覆写?是否存在导致玩笑而不是src / store.js的配置?

1 个答案:

答案 0 :(得分:0)

我想出了自己的问题。如果其他新手开玩笑会从我的愚蠢中受益,将会在这里发布。

Jest不会加载src / store.js。罪魁祸首是我的浅层组件测试,因为组件具有如下语句:

#import "UnityAppController.h"
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <AuthenticationServices/AuthenticationServices.h>

extern UIViewController *UnityGetGLViewController();
@interface SWA:UIViewController<ASAuthorizationControllerDelegate,ASAuthorizationControllerPresentationContextProviding>
@end

@implementation SWA


- (instancetype)init
{
    self = [super init];
    if (self) {
        NSLog(@"Initialize SWA:%s", __FUNCTION__);
        [self observeAppleSignInState];
    }
    return self;
}
//Alert
+(void)alertView:(NSString*)title addMessage:(NSString*) message
{
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title
                                                                   message:message preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];

    [alert addAction:defaultAction];
    [UnityGetGLViewController() presentViewController:alert animated:YES completion:nil];
}

//Sign in with apple
-(void)SignInWithApple
{

    //We can its iOS 13 +
    if (@available(iOS 13.0, *)) {

        // A mechanism for generating requests to authenticate users based on their Apple ID.
        ASAuthorizationAppleIDProvider *appleIDProvider = [ASAuthorizationAppleIDProvider new];

        // Creates a new Apple ID authorization request.
        ASAuthorizationAppleIDRequest *request = appleIDProvider.createRequest;
        // The contact information to be requested from the user during authentication.
        request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];

        // A controller that manages authorization requests created by a provider.
        ASAuthorizationController *controller = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];

        // A delegate that the authorization controller informs about the success or failure of an authorization attempt.
        controller.delegate = self;

        // A delegate that provides a display context in which the system can present an authorization interface to the user.
        controller.presentationContextProvider = self;

        // starts the authorization flows named during controller initialization.
        [controller performRequests];

    }

}
#pragma mark - Delegate
//! Tells the delegate from which window it should present content to the user.
 - (ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller  API_AVAILABLE(ios(13.0)){
    NSLog(@"window:%s", __FUNCTION__);
    return UnityGetGLViewController().view.window;
}

-(void)observeAppleSignInState {
    NSLog(@"Watching SWA:%s", __FUNCTION__);
    if (@available(iOS 13.0, *)) {
        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
        [center addObserver:self selector:@selector(handleSignInWithAppleStateChanged:) name:ASAuthorizationAppleIDProviderCredentialRevokedNotification object:nil];
    }
}

- (void)handleSignInWithAppleStateChanged:(id)noti {
    NSLog(@"%s", __FUNCTION__);
    NSLog(@"%@", noti);
}


 - (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization  API_AVAILABLE(ios(13.0)){

    NSLog(@"%s", __FUNCTION__);
    NSLog(@"%@", controller);
    NSLog(@"%@", authorization);

    NSLog(@"authorization.credential:%@", authorization.credential);

    NSMutableString *mStr = [NSMutableString string];

    if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
        // ASAuthorizationAppleIDCredential
        ASAuthorizationAppleIDCredential *appleIDCredential = authorization.credential;
        NSString *user = appleIDCredential.user;

        [mStr appendString:user?:@""];
        NSString *familyName = appleIDCredential.fullName.familyName;
        [mStr appendString:familyName?:@""];
        NSString *givenName = appleIDCredential.fullName.givenName;
        [mStr appendString:givenName?:@""];
        NSString *email = appleIDCredential.email;
        [mStr appendString:email?:@""];
        NSLog(@"mStr:%@", mStr);
        [mStr appendString:@"\n"];


    } else if ([authorization.credential isKindOfClass:[ASPasswordCredential class]]) {
        ASPasswordCredential *passwordCredential = authorization.credential;
        NSString *user = passwordCredential.user;
        NSString *password = passwordCredential.password;
        [mStr appendString:user?:@""];
        [mStr appendString:password?:@""];
        [mStr appendString:@"\n"];
        NSLog(@"mStr:%@", mStr);
    } else {
         mStr = [@"check" mutableCopy];
    }
}

- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error  API_AVAILABLE(ios(13.0)){

    NSLog(@"%s", __FUNCTION__);
    NSLog(@"error :%@", error);
    NSString *errorMsg = nil;
    switch (error.code) {
        case ASAuthorizationErrorCanceled:
            errorMsg = @"ASAuthorizationErrorCanceled";
            break;
        case ASAuthorizationErrorFailed:
            errorMsg = @"ASAuthorizationErrorFailed";
            break;
        case ASAuthorizationErrorInvalidResponse:
            errorMsg = @"ASAuthorizationErrorInvalidResponse";
            break;
        case ASAuthorizationErrorNotHandled:
            errorMsg = @"ASAuthorizationErrorNotHandled";
            break;
        case ASAuthorizationErrorUnknown:
            errorMsg = @"ASAuthorizationErrorUnknown";
            break;
    }

    NSMutableString *mStr = [NSMutableString string];
    [mStr appendString:errorMsg];
    [mStr appendString:@"\n"];

    NSLog(@"mStr:%@", mStr);

    if (errorMsg) {
        return;
    }

    if (error.localizedDescription) {
        NSMutableString *mStr = [NSMutableString string];
        [mStr appendString:error.localizedDescription];
        [mStr appendString:@"\n"];

        NSLog(@"mStr:%@", mStr);
    }
    NSLog(@"controller requests:%@", controller.authorizationRequests);

}


//If sign in with apple available
+(bool)CanSingIn
{
    if (@available(iOS 13.0, *)) {
        return true;
    }else{
        return false;
    }
}

extern "C"
{
    void _ShowAlert(const char *title, const char *message)
    {
        SWA *classObject = [[SWA alloc] init];
        [classObject SignInWithApple];
//        [SWA alertView:[NSString stringWithUTF8String:title] addMessage:[NSString stringWithUTF8String:message]];
    }

    bool canSignIn(){
        return [SWA CanSingIn];
    }
}

@end

从组件对api的调用如下:

import StuffService from '../../api/stuff';

但是在定义StuffService的es6模块中,顶部有类似的内容:

// e.g. from componentDidMount
StuffService.get.myRequest();

这就是导致src / store保持运行的原因。将研究Jest的Manual Mocks作为解决方案。