首页 \ 问答 \ 工厂方法模式是否可能没有抽象方法?(Is Factory Method pattern without abstract methods possible?)

工厂方法模式是否可能没有抽象方法?(Is Factory Method pattern without abstract methods possible?)

假设一个没有抽象方法的Java程序,是否可以在没有抽象方法的情况下实现Factory Method模式?


Let's say one Java program that does not have abstract methods, is it possible to implement the Factory Method pattern without abstract methods?


原文:https://stackoverflow.com/questions/19255288
更新时间:2023-11-10 11:11

最满意答案

官方复数页面复制了一些代码提取

要进行身份验证的端点位于config/routes.rb

post 'authenticate', to: 'authentication#authenticate'

执行此操作。 如果您正确进行身份验证,操作将返回令牌。

def authenticate 
   command = AuthenticateUser.call(params[:email], params[:password]) 
   if command.success? 
      render json: { auth_token: command.result } 
   else 
      render json: { error: command.errors }, status: :unauthorized 
   end 
end

在rspec中,您有两个选项,您可以模拟此方法或创建工厂。

token based身份验证的概念是,一旦经过身份验证,用户将拥有令牌,并且通过提供此令牌,他将能够访问仅保留给用户的功能

请求

$ curl -H "Content-Type: application/json" -X POST -d '{"email":"example@mail.com","password":"123123123"}' http://localhost:3000/authenticate

作为回应令牌

{"auth_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE0NjA2NTgxODZ9.xsSwcPC22IR71OBv6bU_OGCSyfE89DvEzWfDU0iybMA"}

如果您在标头中包含令牌,请求将不会触发授权错误

$ curl -H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE0NjA2NTgxODZ9.xsSwcPC22IR71OBv6bU_OGCSyfE89DvEzWfDU0iybMA" http://localhost:3000/items []

所以在执行get请求之前,请在请求标头中包含令牌

request.headers['Authorization'] = auth_token
get :your_action

如何提供正确的auth_token值?

您需要在ApplicationController 模拟 authenticate_request方法,因为它在action before被调用

#app/controllers/application_controller.rb
class ApplicationController < ActionController::API
 before_action :authenticate_request
  attr_reader :current_user

  private

  def authenticate_request
    @current_user = AuthorizeApiRequest.call(request.headers).result
    render json: { error: 'Not Authorized' }, status: 401 unless @current_user
  end
end

我相信你应该模拟这行代码,以避免收到身份验证错误。

@current_user = AuthorizeApiRequest.call(request.headers).result

所以我会写一些像这样的规格

user = FactoryBot.create(:user)
allow(AuthorizeApiRequest).to receive(:call).and_return(user)
# request.headers['Authorization'] = auth_token # this is not required anymore the authentication is skipped
get :your_action

我引用了复数

通过使用before_action,每次用户发出请求时,服务器都会将request headers (使用内置对象属性request.headers)传递给AuthorizeApiRequest 。 在AuthorizeApiRequest.call(request.headers)上调用result来自SimpleCommand模块,其中定义为attr_reader :result 。 请求结果将返回给@current_user ,从而可供从ApplicationController继承的所有控制器使用。

你可以阅读更多关于嘲笑的内容

https://github.com/rspec/rspec-mocks


Some Code Extracts copied from the the official pluralsight page

the endpoint to authenticate is in config/routes.rb

post 'authenticate', to: 'authentication#authenticate'

which executes this action. The action returns the token if you correctly authenticate.

def authenticate 
   command = AuthenticateUser.call(params[:email], params[:password]) 
   if command.success? 
      render json: { auth_token: command.result } 
   else 
      render json: { error: command.errors }, status: :unauthorized 
   end 
end

In rspec you have two options, you either mock this method or create a factory.

The concept of token based authentication is that once authenticated the user will have a token and by providing this token he will be able to access the functionalities only reserved to users

The request

$ curl -H "Content-Type: application/json" -X POST -d '{"email":"example@mail.com","password":"123123123"}' http://localhost:3000/authenticate

gives in response the token

{"auth_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE0NjA2NTgxODZ9.xsSwcPC22IR71OBv6bU_OGCSyfE89DvEzWfDU0iybMA"}

if you include in the header the token, the request will not trigger an authorization error

$ curl -H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE0NjA2NTgxODZ9.xsSwcPC22IR71OBv6bU_OGCSyfE89DvEzWfDU0iybMA" http://localhost:3000/items []

so before doing your get request, include in the request header the token

request.headers['Authorization'] = auth_token
get :your_action

How to provide a correct value of auth_token?

You will need to mock the method authenticate_request in ApplicationController, as it is called before the action

#app/controllers/application_controller.rb
class ApplicationController < ActionController::API
 before_action :authenticate_request
  attr_reader :current_user

  private

  def authenticate_request
    @current_user = AuthorizeApiRequest.call(request.headers).result
    render json: { error: 'Not Authorized' }, status: 401 unless @current_user
  end
end

I believe you should mock this line of code, to avoid receiving an authentication error.

@current_user = AuthorizeApiRequest.call(request.headers).result

so I would write the specs somethind like this

user = FactoryBot.create(:user)
allow(AuthorizeApiRequest).to receive(:call).and_return(user)
# request.headers['Authorization'] = auth_token # this is not required anymore the authentication is skipped
get :your_action

I quote pluralsight

By using before_action, the server passes the request headers (using the built-in object property request.headers) to AuthorizeApiRequest every time the user makes a request. Calling result on AuthorizeApiRequest.call(request.headers) is coming from SimpleCommand module where it is defined as attr_reader :result. The request results are returned to the @current_user, thus becoming available to all controllers inheriting from ApplicationController.

You can read more about mocking at

https://github.com/rspec/rspec-mocks

相关问答

更多
  • 从官方复数页面复制了一些代码提取 要进行身份验证的端点位于config/routes.rb post 'authenticate', to: 'authentication#authenticate' 执行此操作。 如果您正确进行身份验证,操作将返回令牌。 def authenticate command = AuthenticateUser.call(params[:email], params[:password]) if command.success? render ...
  • 尝试: expect(confirmation_email.body.encoded).to include 'You can confirm your account email' Try: expect(confirmation_email.body.encoded).to include 'You can confirm your account email'
  • 当单个规范的执行成功但同一规范在作为较大套件的一部分运行时失败时,它表示其他测试的先前执行正在影响结果。 如果有问题的规范是深层嵌套的,就像在这种情况下,隔离问题的一种方法是从相关规范中运行连续目录中的所有规范,直到导致失败。 一旦找到导致问题的目录,就可以通过指定在失败测试之前运行的不同系列规范来进一步隔离,直到您找出有问题的规范。 例如,在这种情况下,您将运行rspec spec/requests/api/v1 ,如果成功,则运行rspec spec/requests/api ,如果成功则运行rspec ...
  • 像这样使用它: get '/api/v1/projects/1', {}, { Authorization: "Token 123"} get是http方法, {}是一个空的参数, { :Authorization => "Token 123"}标题 get(path,parameters = nil,headers_or_env = nil) Documentation 另一种方式: before do # some code here @request.env['Authoriza ...
  • 我最后重构了很多其他代码来运行在实际控制器中创建实例变量的身份验证方法。 我不相信有一种方法可以在Rspec中设置变量以用于GET请求。 使用集成测试来测试authenticate_with_http_token ,您需要在GET请求中包含它: get '/v1/path-for-api', nil, authorize: 'Token token=#{user.token}' 从那里开始,变量已经正确设置,我能够测试请求。 I ended up refactoring quite a bit of oth ...
  • 似乎POST参数是JSON编码的。 795: unexpected token at 'myparam'当应用程序尝试JSON解码未编码的参数时,会导致795: unexpected token at 'myparam' 。 使用.to_json和post params。 post api_v1_post_path(@myid), {"myparam" => "myvalue"}.to_json , {"X-Some-Header" => "MyValue"} 您可能想要使用let: describe ' ...
  • 在对Reddit进行了大量研究和对话后 ,似乎最好的方法就是通过拦截器。 在.config或.run块中进行设置可能有助于检查用户在首次加载应用程序时是否已经过身份验证(如果本地存储中有令牌),但无法处理动态更改,例如在加载应用程序后注销或登录。 我很确定你可以通过$ http默认标头来实现,但也可以在一个地方进行。 希望这有助于未来的人! After a bunch more research and a conversation on Reddit, it seems like the best way ...
  • 起初,我以这种方式创建了网络应用上下文 mockMvc = webAppContextSetup(webApplicationContext).apply(springSecurity()).build(); 但解决方案是获取SessionRepositoryFilter过滤器的实例并将其添加到Web应用程序上下文中。 过滤器负责返回x-auth-token标头。 SessionRepositoryFilter filter = webApplicationContext.getBean(Sessi ...
  • 正确的答案是避免非常复杂的观点。 如果视图中几乎没有逻辑,那么可能没有必要对其进行测试。 将逻辑提取到演示者中 ,这样就可以更容易地进行测试。 我没有使用视图测试来测试我的视图,因为维护它们通常不是很有趣。 一些功能规格在这里给了我足够的安全性。 如果您仍想测试它,您可能希望使用预期的参数调用render : expect(view).to receive(:render).with(@employee.contacts) 不确定视图是否可通过view 。 PS:不要只是避免编写复杂的视图,避免复杂的代码 ...
  • it { should respond_with 401 }没有指定哪个对象应该用401响应,这就是错误的原因。 要修复它,请尝试: expect(response).to respond_with 401 或使用主题 : subject{ response } it { should respond_with 401 } it { should respond_with 401 } does not specify which object should repond with 401, that ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。