如何为控制器编写可测试的代码

时间:2018-12-18 14:13:38

标签: php laravel

我写了一个laravel代码,我感到沮丧,因为我认为我写的任何东西都是不好的代码,无法测试。我将发布我的代码。

如您所见,我正在控制器中直接使用模型。但是我只需要知道如何编写laravel控制器代码的最佳方法就可以如此灵活和可测试。我认为在这里显示的代码似乎无法测试。你觉得怎么样?

这是我的控制者:

class AuthController extends Controller
{

    protected $auth;
    protected $notification;

    public function __construct(AuthHelper $auth, NotificationHelper $notification){
        $this->auth = $auth;
        $this->notification = $notification;
    }


    public function loginUser(UserLoginRequest $request){
        $credentials = $request->only('email', 'password');
        return $this->auth->generateJwtAndRefreshToken($credentials);
    }


    public function registerUser(UserRegisterRequest $request){
        $user = new User();
        $user->name = $request->name;
        $user->email = $request->email;
        $user->password =  \Hash::make($request->password);
        $user->country_id = $request->country_id;
        $user->phone = $request->phone;
        $user->address = $request->address;

        return $this->auth->registerUserHelper($request, $user, $this->notification);
    }
}

这是我的助手课

<?php
namespace App\Http\Helpers;

use Tymon\JWTAuth\Facades\JWTAuth;
use App\Http\Models\Users\User;
use App\Http\Models\Users\TokenUser;
use App\Http\Helpers\NotificationHelper;
use App\Http\Models\Users\EmailConfirmation;
use App\Http\Models\Users\PasswordResetConfirmation;
use App\Http\Models\Permissions\Role;
use Carbon\Carbon;
use DB;

class AuthHelper {

    // generates guuid which will be called refresh token.
    public function generateRefreshToken(){
        mt_srand((double)microtime()*10000); //optional for php 4.2.0 and up.
        $charid = strtoupper(md5(uniqid(rand(), true)));
        $hyphen = chr(45);// "-"
        $uuid = substr($charid, 0, 8).$hyphen
            .substr($charid, 8, 4).$hyphen
            .substr($charid,12, 4).$hyphen
            .substr($charid,16, 4).$hyphen
            .substr($charid,20,12);
        return  $uuid;
    }



    /* generates access and refresh token while logging a user */
    public function generateJwtAndRefreshToken($credentials){
        try {
            if (! $access_token = JWTAuth::attempt($credentials)) {
                return response()->json(['message' => trans("errors.user_not_exists")], 404);
            }
        } catch (JWTException $e) {
            return response()->json(['message' => trans("errors.500")], 500);
        }
        $refresh_token = $this->generateRefreshToken();
        $user = JWTAuth::user();
        $refreshTokenUser = TokenUser::updateOrCreate(
            ['user_id' => $user->id],
            ['refresh_token' => $refresh_token, 'expiration_date' => Carbon::now()->addMinutes(\Config::get("jwt.refresh_token_expiration"))]
        );
        if(!$refreshTokenUser){
            return response()->json(['message' => trans("errors.500") ], 500);
        }
        return response()->json([ 
            'access_token' => $access_token,
            'refresh_token' => $refresh_token
        ], 200);
    }


    public function registerUserHelper($request, $user, $notification){
        $confirmation_code = str_random(6);
        DB::beginTransaction();
        try{
            $role_id = Role::where("name", $request->role_name)->first()->id;
            EmailConfirmation::create([
                'code' => $confirmation_code, 
                'email' => $request->email, 
                'expires_at' => Carbon::now()->addHour()
            ]);
            $user->save();
            $user->roles()->attach($role_id);
            $userTokens  = $this->generateJwtAndRefreshToken($request->only("email", "password"));
            if($userTokens->status() != 200) throw new \Exception();

            DB::commit();
        }catch(\Exception $e){
            DB::rollback();
            return response()->json(['message'=> trans('errors.500')],500); 
        }

        $notification->sendMail(['to' => $request->email, 'template_name' =>'RegisterVerification', 'confirmation' => $confirmation_code]);
        return response()->json(['message'=> trans('errors.registered'),'user_token' => $userTokens->getOriginalContent()], 200); 

    }

1 个答案:

答案 0 :(得分:0)

为此,我建议您使用两种模式。

  1. 存储库模式,它可以帮助您在模型和模型客户端之间创建一个层。因此,所有内容都将从存储库访问,而模型和模型将用于编写每个存储库。 https://medium.com/employbl/use-the-repository-design-pattern-in-a-laravel-application-13f0b46a3dce此链接可以使您进一步了解存储库模式。

  2. 服务层,这是一个包含所有业务逻辑类作为服务的层。最终,您将在控制器中使用服务。 https://m.dotdev.co/design-pattern-service-layer-with-laravel-5-740ff0a7b65f这可以澄清服务层。

基本上,服务使用存储库来进行所有数据库交互,而不是直接在控制器中进行。