我知道这是一个非常常见的问题,但其他任何回复都无法帮助我。
我目前正在尝试为我的网站创建测试,但我总是收到错误
ActionView :: Template ::错误:未定义的方法
我的很多方法通常会产生Nill
类。该网站使用设计登录。
这是我正在尝试运行的测试。我确保我的灯具已装入测试数据库
require 'test_helper'
class PagesControllerTest < ActionController::TestCase
include Devise::TestHelpers
include Warden::Test::Helpers
Warden.test_mode!
def setup
sign_in User.first
end
def teardown
Warden.test_reset!
end
test "should get index" do
get :index
assert_response :success
end
test "should get voting" do
get :voting
assert_response :success
end
end
这些是尝试运行测试时的错误消息
Minitest::UnexpectedError: ActionView::Template::Error: undefined method `strip' for nil:NilClass
config/initializers/addChallenges.rb:22:in `findChallenges'
app/views/pages/index.html.erb:11:in `_app_views_pages_index_html_erb__190802989_69818040'
test/controllers/pages_controller_test.rb:18:in `block in <class:PagesControllerTest>'
config/initializers/addChallenges.rb:22:in `findChallenges'
app/views/pages/index.html.erb:11:in `_app_views_pages_index_html_erb__190802989_69818040'
test/controllers/pages_controller_test.rb:18:in `block in <class:PagesControllerTest>'
Minitest::UnexpectedError: ActionView::Template::Error: undefined method `strip' for nil:NilClass
config/initializers/addIdeas.rb:25:in `findIdeas'
app/views/pages/voting.html.erb:6:in `_app_views_pages_voting_html_erb___557022735_70668940'
test/controllers/pages_controller_test.rb:24:in `block in <class:PagesControllerTest>'
config/initializers/addIdeas.rb:25:in `findIdeas'
app/views/pages/voting.html.erb:6:in `_app_views_pages_voting_html_erb___557022735_70668940'
test/controllers/pages_controller_test.rb:24:in `block in <class:PagesControllerTest>'
Finished in 0.31402s
2 tests, 0 assertions, 0 failures, 2 errors, 0 skips
Process finished with exit code 0
在这种情况下跟踪错误时,此行显示为有问题resp = http.get(url.path, headers)
这是我的完整addIdeas代码,但addChallenges代码非常相似。
class AddIdeas
#a method that will find all the challenge ideas for a user and then store them in our databse
def self.findIdeas(email,challengeId)
require "net/http"
require "uri"
require 'json'
require 'active_record'
p= People.find_by_email(email)
uri_string = 'http://sideways6.com/api/V1/Idea/Challenge/'
uri_string << challengeId.to_s
#make the http request with the headers
url = URI.parse(uri_string)
http = Net::HTTP.new(url.host, url.port)
headers = {
'Authorization' => p.basic,
'UserId' => p.userId,
'AuthorizationToken' => p.auth_tok
}
#retrieve a get response
resp = http.get(url.path, headers)
#if response is okay parse the challenge ids and add them to the person table for that user
if resp.code.to_s == '200'
if resp.body.to_s != 'null'
puts parsed = JSON.parse(resp.body)
ids = ""
parsed.each do |element|
addIdeas(element, challengeId)
ids << "#{element['IdeaId']},"
end
c = Challenges.find_by_challengeId(challengeId)
c.ideaIds = ids
c.save
end
end
end
def self.addIdeas(element, challengeId)
i = Ideas.find_by_ideaId(element['IdeaId'])
if i == nil
i = Ideas.create(:ideaId => element['IdeaId'], :title => element['Title'], :description => element['Description'], :challengeIds => challengeId, :score=>1000, :faceOff => 0, :wins =>0)
end
if i != nil
i.ideaId = (element['IdeaId'])
i.title = (element['Title'])
i.description = (element['Description'])
i.challengeIds = challengeId
i.save
end
end
def self.findAllIdeas(email)
p = People.find_by_email(email)
ids = p.challenges
splitted = ids.split(",")
counter = splitted.length
i =0
while i < counter.to_i do
findIdeas(email, splitted[i])
i += 1
end
end
end
addChallenges文件
class AddChallenges
#a method that will find all the challenge ideas for a user and then store them in our databse
def self.findChallenges(email)
require "net/http"
require "uri"
require 'json'
require 'active_record'
p= People.find_by_email(email)
#make the http request with the headers
url = URI.parse('http://sideways6.com/api/V1/Challenge/All')
http = Net::HTTP.new(url.host, url.port)
headers = {
'Authorization' => p.basic,
'UserId' => p.userId,
'AuthorizationToken' => p.auth_tok
}
#retrieve a get response
resp = http.get(url.path, headers)
#if response is okay parse the challenge ids and add them to the person table for that user
if resp.code.to_s == '200'
puts parsed = JSON.parse(resp.body)
ids = ""
parsed.each do |element|
addChallenges(element)
ids << "#{element['ChallengeId']},"
end
p = People.find_by_email(email)
p.challenges = ids
p.save
end
end
def self.addChallenges(element)
c = Challenges.find_by_challengeId(element['ChallengeId'])
if c == nil
c = Challenges.create(:challengeId => element['ChallengeId'], :title => element['Title'], :description => element['Description'])
end
if c != nil
c.challengeId = (element['ChallengeId'])
c.title = (element['Title'])
c.description = (element['Description'])
c.save
end
end
def self.retrieveChallengeObject(challengeId)
c = Challenges.find_by_challengeId(challengeId)
end
end
我的页面控制器按要求
class PagesController <ApplicationController
def home
@current_nav_identifier = :home
end
end
索引页
<script type="text/javascript">window._token = '<%= form_authenticity_token %>';</script>
<body>
<noscript>
<div class='warning-page-cover'>
<div class='alert alert-info'>
<h2>Sorry about that, it appears that you are using a web browser without JavaScript which prevents us offering you a rich online experience.</h2>
<p>Please enable JavaScript or use a different web browser, or alternatively contact the CiCS Helpdesk for assistance.</p>
</div>
</div>
</noscript>
<%AddChallenges.findChallenges(current_user.email)%>
<%AddIdeas.findAllIdeas(current_user.email)%>
<div id='wrap'>
<nav class='navbar navbar-default navbar-fixed-top' id='main-nav'>
<div class='container-fluid'>
<div class='navbar-header'>
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class='icon-bar'></span>
<span class='icon-bar'></span>
<span class='icon-bar'></span>
</button>
<a href="<%= url_for(:controller=> 'pages', :action => 'index')%>">
<%= image_tag('/logo.png', :alt => "Sideways 6 Logo", size:"203x50") %>
</a>
</div>
<div class='collapse navbar-collapse' id="bs-example-navbar-collapse-1">
<ul class='nav navbar-nav'>
</ul>
<% if true # user_signed_in? %>
<ul class="nav navbar-nav navbar-right">
<li><%= link_to fa_icon('index', text: 'Refresh Challenges'), root_path , method: :get %></li>
<li class="dropdown">
<%= link_to '#', data: { toggle: :dropdown }, class: 'dropdown-toggle' do %>
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
<% p = People.find_by_email(current_user.email)%>
<% fName = p.firstName %>
<% if fName != nil %>
<%= fa_icon('user', text: fName )%>
<%end%>
<% if fName == nil %>
<%= fa_icon('user', text: current_user.email) %>
<%end%>
<b class="caret"></b>
<% end %>
<ul class="dropdown-menu">
<li>
<%# log out path is usually: destroy_user_session_path %>
<%= link_to fa_icon('index', text: Score.retrieveUserScore(current_user.email)), root_path , method: :get %>
<%= link_to fa_icon('challenges', text:'All Challenges'), challenges_path, method: :get, title: "See all Challenges" %>
<%= link_to fa_icon('sign-out', text: 'Log out'), destroy_user_session_path, method: :get, title: "Log out of the system" %>
</li>
</ul>
</li>
</ul>
<% end %>
</div>
</div>
</nav>
<div id="main">
<h1>Select A Challenge To Vote On</h1>
<% p = People.find_by_email(current_user.email) %>
<% ids = p.challenges %>
<% splitted = ids.split(",") %>
<% counter = splitted.length %>
<p class="lead">Please Select One</p>
<% i =0 %>
<% while i < counter.to_i do %>
<div class="row">
<div class="col-xs-12 col-md-6">
<% c = AddChallenges.retrieveChallengeObject(splitted[i]) %>
<% if Vote.canVote(splitted[i]) == true %>
<a href="<%= url_for(:controller=> 'pages', :action => 'voting')%>?challengeId=<%=(splitted[i])%>" class="challenge-select" data-challengeid="<%=(splitted[i])%>">
<div class="well clickable">
<h4><%= c.title %></h4>
<p class="text-center"> <%= c.description %> </p>
</div>
</a>
<% end %>
</div>
<% i+=1 %>
<% if i != counter %>
<div class="col-xs-12 col-md-6">
<% c = AddChallenges.retrieveChallengeObject(splitted[i]) %>
<% if Vote.canVote(splitted[i]) == true %>
<a href="<%= url_for(:controller=> 'pages', :action => 'voting')%>?challengeId=<%=(splitted[i])%>" class="challenge-select" data-challengeid="<%=(splitted[i])%>">
<div class="well clickable">
<h4><%= c.title %></h4>
<p class="text-center"><%= c.description %></p>
</div>
</a>
<% end %>
</div>
<%end%>
</div>
<% i+=1 %>
<%end%>
<%= yield %>
</div>
</div>
投票html
<script type="text/javascript">window._token = '<%= form_authenticity_token %>';</script>
<% require 'digest/sha1'
salt = '%+5)_' %>
<% AddIdeas.findIdeas(current_user.email,params[:challengeId]) %>
<% if params[:winner] != nil
concat = "#{salt}#{params[:challengeId]}#{params[:winner]}#{params[:loser]}#{salt}"
hash = Digest::SHA1.hexdigest(concat)
if hash == params[:hash]
Score.updateScore(params[:winner],params[:loser])
Score.userScore(current_user.email)
end
end %>
<div id='wrap'>
<nav class='navbar navbar-default navbar-fixed-top' id='main-nav'>
<div class='container-fluid'>
<div class='navbar-header'>
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class='icon-bar'></span>
<span class='icon-bar'></span>
<span class='icon-bar'></span>
</button>
<a href="<%= url_for(:controller=> 'pages', :action => 'index')%>">
<%= image_tag('/logo.png', :alt => "Sideways 6 Logo", size:"203x50") %>
</a>
</div>
<div class='collapse navbar-collapse' id="bs-example-navbar-collapse-1">
<ul class='nav navbar-nav'>
</ul>
<% if true # user_signed_in? %>
<ul class="nav navbar-nav navbar-right">
<li><%= link_to fa_icon('index', text: 'Change Challenge'), root_path , method: :get %></li>
<li class="dropdown">
<%= link_to '#', data: { toggle: :dropdown }, class: 'dropdown-toggle' do %>
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
<% p = People.find_by_email(current_user.email)%>
<% fName = p.firstName %>
<% if fName != nil %>
<%= fa_icon('user', text: fName )%>
<%end%>
<% if fName == nil %>
<%= fa_icon('user', text: current_user.email) %>
<%end%>
<b class="caret"></b>
<% end %>
<ul class="dropdown-menu">
<li>
<%# log out path is usually: destroy_user_session_path %>
<%= link_to fa_icon('index', text: Score.retrieveUserScore(current_user.email)), root_path , method: :get %>
<%= link_to fa_icon('challenges', text:'All Challenges'), challenges_path, method: :get, title: "See all Challenges" %>
<%= link_to fa_icon('sign-out', text: 'Log out'), destroy_user_session_path, method: :get, title: "Log out of the system" %>
</li>
</ul>
</li>
</ul>
<% end %>
</div>
</div>
</nav>
<div id="main">
<% c = Challenges.find_by_challengeId(params[:challengeId]) %>
<% ids = c.try(:ideaIds) %>
<% splitted = ids.try(:split, ",") %>
<% shuffle = splitted.try(:shuffle) %>
<% firstIdea = shuffle.try(:first) %>
<% lastIdea = shuffle.try(:last) %>
<% f = Ideas.find_by_ideaId(firstIdea)%>
<% l = Ideas.find_by_ideaId(lastIdea)%>
<h1><%=c.try(:title)%></h1>
<p class="lead">Which best solves the challenge?</p>
<div class="row">
<div class="col-xs-12 col-md-6">
<% challengeId = params[:challengeId]
winner = f.try(:ideaId)
loser = l.try(:ideaId)
concat = "#{salt}#{challengeId}#{winner}#{loser}#{salt}"
hash = Digest::SHA1.hexdigest(concat) %>
<a href="<%= url_for(:controller=> 'pages', :action => 'voting')%>?challengeId=<%=(params[:challengeId])%>&winner=<%=(f.try(:ideaId))%>&loser=<%=(l.try(:ideaId))%>&hash=<%=(hash)%>" class="idea-vote" data-challengeid="<%=(params[:challengeId])%>" data-winner="<%=(f.try(:ideaId))%>" data-loser="<%=(l.try(:ideaId))%>" data-hash="<%=(hash)%>">
<div class="well clickable">
<h4><%= f.try(:title) %></h4>
<p class="text-center"><%= f.try(:description)%></p>
</div>
</a>
</div>
<div class="col-xs-12 col-md-6">
<% challengeId = params[:challengeId]
winner = l.try(:ideaId)
loser = f.try(:ideaId)
concat = "#{salt}#{challengeId}#{winner}#{loser}#{salt}"
hash = Digest::SHA1.hexdigest(concat) %>
<a href="<%= url_for(:controller=> 'pages', :action => 'voting')%>?challengeId=<%=(params[:challengeId])%>&winner=<%=(l.try(:ideaId))%>&loser=<%=(f.try(:ideaId))%>&hash=<%=(hash)%>" class="idea-vote" data-challengeid="<%=(params[:challengeId])%>" data-winner="<%=(l.try(:ideaId))%>" data-loser="<%=(f.try(:ideaId))%>" data-hash="<%=(hash)%>">
<div class="well clickable">
<h4><%=l.try(:title)%></h4>
<p class="text-center"><%=l.try(:description)%></p>
</div>
</a>
</div>
</div>
<a href="<%= url_for(:controller=> 'pages', :action => 'voting')%>?challengeId=<%=(params[:challengeId])%>" class="btn btn-default btn-sm">Skip <span class="glyphicon glyphicon-chevron-right"></span></a>
<%= yield %>
</div>
</div>
我尝试使用try()
修改方法,似乎有时会解决问题,但之后try()
会导致网站本身出现问题。有时,错误消息会将我重定向到使用方法的html视图文件本身。
编辑: 修好标题后我现在好了
Minitest::UnexpectedError: ActionView::Template::Error: undefined method `split' for nil:NilClass
config/initializers/addIdeas.rb:61:in `findAllIdeas'
app/views/pages/index.html.erb:12:in `_app_views_pages_index_html_erb__1448445017_66568380'
test/controllers/pages_controller_test.rb:17:in `block in <class:PagesControllerTest>'
config/initializers/addIdeas.rb:61:in `findAllIdeas'
app/views/pages/index.html.erb:12:in `_app_views_pages_index_html_erb__1448445017_66568380'
test/controllers/pages_controller_test.rb:17:in `block in <class:PagesControllerTest>'
Minitest::UnexpectedError: ActionView::Template::Error: undefined method `score' for #<People:0x000000085d17b0>
config/initializers/score.rb:50:in `retrieveUserScore'
app/views/pages/voting.html.erb:56:in `_app_views_pages_voting_html_erb___944539514_69504160'
test/controllers/pages_controller_test.rb:23:in `block in <class:PagesControllerTest>'
config/initializers/score.rb:50:in `retrieveUserScore'
app/views/pages/voting.html.erb:56:in `_app_views_pages_voting_html_erb___944539514_69504160'
test/controllers/pages_controller_test.rb:23:in `block in <class:PagesControllerTest>'
Finished in 0.53103s
2 tests, 0 assertions, 0 failures, 2 errors, 0 skips
Process finished with exit code 0
score.rb文件
class Score
def self.updateScore(winner, loser)
Math.exp(1)
w = Ideas.find_by_ideaId(winner)
l = Ideas.find_by_ideaId(loser)
# updatewinner
# games W played = get number of times the winner has matched up against other ideas
# winner new score = winner score + (1000/games W played) (1+ 1/(1 + Math.exp(loser score - winner score)))
w.faceOff += 1
w.save
lScore = l.score
wScore = w.score
wGames = w.faceOff
newWScore = wScore + (500/wGames)*(1-(1/(1 + Math.exp(lScore - wScore))))
l.faceOff += 1
l.save
lGames = l.faceOff
newLScore = lScore + (500/lGames)*(-1/(1+ Math.exp(wScore - lScore)))
puts "New Winner Score "
puts newWScore
w.score = newWScore
w.save
puts "New Loser Score "
puts newLScore
l.score = newLScore
l.save
puts newWScore
# updateloser
# games L played = get number of times the loser has matched up against other ideas
# loser new score = loser score + (1000/games L played) (1+ 1/(Math.exp(winner score - loser score)))
end
def self.userScore(email)
p = People.find_by_email(email)
score = p.score
newScore = score + 1
p.score = newScore
p.save
end
def self.retrieveUserScore(email)
p = People.find_by_email(email)
score = 'Score: ' << p.score.to_s
end
end
答案 0 :(得分:1)
好的,我做了一些测试:
您的错误是header
参与者之一以[{1}}
我可以通过设置
来复制您的错误nil
并运行headers = {
'Authorization' => nil,
'UserId' => nil,
'AuthorizationToken' => nil
}
你可以做些什么来避免异常,让API返回错误是测试nil并用空字符串替换http.get(url.path, headers)
例如:""
编辑:对于您上面的编辑...
有两个错误:
'Authorization' => p.basic || ""
这是因为:
ActionView::Template::Error: undefined method 'split' for nil:NilClass
ids = p.challenges
如果ID为零,则无法在其上调用splitted = ids.split(",")
。您需要在此时添加一个检查并返回。
split
您的ActionView::Template::Error: undefined method 'score' for #<People:0x000000085d17b0>
模型没有People
方法