I have this module in my lib folder:
module Exceptions
class NotAuthorized < StandardError
end
end
Then, I have a test for a controller like this:
class Admin::ApplicationControllerTest < ActionController::TestCase
test "should not be authorized" do
assert_raise(Exceptions::NotAuthorized) {
get :index
}
end
end
I also try to put this line on my environments/test.rb
config.autoload_paths +=%W(#{config.root}/lib)
But, when I run the test I always get:
NameError: unitialized constant Admin::ApplicationControllerTest::Exceptions
How to include the module Exceptions in the test?
Moving
config.autoload_paths +=%W(#{config.root}/lib)
to application.rb fix it.
Related
I have been trying like mad to use config based mocks on Elixir. I have defined my mocked module and placed it inside a ".ex" file under the "test/" directory. Then whenever I run "mix test" it fails to load the module. However if I move the mock under "lib/" then everything works just fine. So I was wondering if there is something I'm missing on my configuration and file structure OR if there is a way to tell "mix" to look for source files in another directory in addition to "lib/".
File structure:
my_app/
|
+ -- lib/
| my_lib.ex
| my_service.ex
|
+ ---test/
| test_helper.ex
| my_service_mock.ex
| my_lib_test.exs
|
+----config/
config.exs
test.exs
prod.exs
dev.exs
config/dev.exs
import Config
config :my_app, my_service: MyApp.MyService
config/test.exs
import Config
config :my_app, my_service: MyApp.MyServiceMock
my_lib.ex
defmodule MyLib do
#my_service Application.get_env(:my_app, :my_service)
def do_something, do: #my_service.do_something_else
end
my_service.ex
defmodule MyApp.MyService do
def do_something_else, do: { :ok, "Running business task" }
end
my_service_mock.ex
defmodule MyApp.MyServiceMock do
def do_something_else, do: { :ok, "Faking business task" }
end
my_lib_test.ex
defmodule MyApp.MyLibTest do
use ExUnit.Case
alias MyApp.MyLib
test "MyList.do_something/0 should do it's thing" do
assert { :ok, "Faking business task" } = MyLib.do_something
end
end
The command "mix test" fails with the following error:
== Compilation error in file lib/my_lib.ex ==
** (UndefinedFunctionError) function MyApp.MyServiceMock.do_something_else/0 is undefined (module MyApp.MyServiceMock is not available)
MyApp.MyServiceMock.do_something_else()
lib/my_lib.ex:3: (module)
(stdlib 3.14) erl_eval.erl:680: :erl_eval.do_apply/6
I'm running elixir 1.11.2.
Well, I finally found out the solution on this post on Elixir Forum: https://elixirforum.com/t/load-module-during-test/7400
It turns out there is a variable in the "Mix.Project" that specifies the paths for the sources:
So in my "mix.exs" I did the following:
def project do
[
...
elixirc_paths: elixirc_paths(Mix.env),
...
]
end
defp elixirc_paths(env_name) do
case env_name do
:test -> ["lib", "test/mockery"]
_ -> ["lib"]
end
end
Of course I added the directory "test/mockery/" and moved "MyApp.MyServiceMock" there...
We have a unit test suite, written in RSpec. We have some failed tests that is a lot actually.
What I am looking for is a script or a magic command, to mark all the failed tests as skipped, so I don't have to go over them one by one and mark them as skipped.
I found this awesome script that do exactly what I need:
https://gist.github.com/mcoms/77954d191bde31d4677872d2ab3d0cd5
Copying the contents here, in case the original gist is deleted:
# frozen_string_literal: true
class CustomFormatter
RSpec::Core::Formatters.register self, :example_failed
def initialize(output)
#output = output
end
def example_failed(notification)
tf = Tempfile.new
File.open(notification.example.metadata[:file_path]) do |f|
counter = 1
while (line = f.gets)
if counter == notification.example.metadata[:line_number]
line.sub!('it', 'skip')
line.sub!('scenario', 'skip')
#output << line
end
tf.write line
counter += 1
end
end
tf.close
FileUtils.mv tf.path, notification.example.metadata[:file_path]
end
end
Should be relatively straightforward. RSpec lists failing specs like this
rspec ./spec/models/user.rb:67 # User does this thing
rspec ./spec/models/post.rb:13 # Post does another thing
rspec ./spec/models/rating.rb:123 # Rating does something else entirely
File name and line number point to the opening line of the test, the one with it ... do.
Write a script that
extracts file names and line numbers from the failure output
opens those files, goes to the specified line
and replaces it with xit.
I am currently working on a bigger rails application, that uses engines for sub applications, with the following folder structure:
- app
\- controllers
\- global
\- base_controller.rb
\- configurations_controller.rb
\- application_controller.rb
- ...
- engines
\- engine_1
\- app
\- controllers
\- engine_1
\- application_controller.rb
\- global
\- base_controller.rb
\- configurations_controller.rb
- ...
The setup of the controllers is as follows:
# app/controllers/global/base_controller.rb
class Global::BaseController < ApplicationController
end
# app/controllers/global/configurations_controller.rb
class Global::BaseController < Global::BaseController
end
# engines/engine_1/app/controllers/engine_1/application_controller.rb
module Engine1
class ApplicationController < ::ApplicationController
end
end
# engines/engine_1/app/controllers/engine_1/global/base_controller.rb
require_dependency "engine_1/application_controller"
module Engine1
class Global::BaseController < ApplicationController
end
end
# engines/engine_1/app/controllers/engine_1/global/configurations_controller.rb
module Engine1
class Global::ConfigurationsController < Global::BaseController
end
end
My routes files
# config/routes.rb
Rails.application.routes.draw do
namespace :global do
resource :configuration, only: [:show, :update]
end
mount Engine1::Engine, at: '/engine_1', as: :engine_1
end
# engines/engine_1/config/routes.rb
Engine1::Engine.routes.draw do
namespace :global do
resource :configuration, only: [:show, :update]
end
end
In development environment everything works as expected. But in production environment, when the application gets started and classes are being eager loaded, I get a Superclass mismatch exception for Global::BaseController when it tries to load the Global::ConfigurationsController in module Engine1.
I overcame the problem (temporarily) in renaming the Engine1::Global::BaseController but I don't understand why this is not working in production mode only?
The Superclass mismatch error happens when there is a re-definition of a class. According to your question, the error is on BaseController. Here's my theory looking at what you've posted. BaseController is being defined more than once, so that when this code is loaded the BaseController is ambiguous:
module Engine1
class Global::ConfigurationsController < Global::BaseController
end
end
It appears that at load time there are 2 definitions extant of BaseController.
# app/controllers/global/base_controller.rb
class Global::BaseController < ApplicationController
end
# app/controllers/global/configurations_controller.rb
class Global::BaseController < Global::BaseController
end
So which BaseController should be loaded? To you it is obvious what should be done here, and I think I understand what you're trying to do with adding a level of indirection to your configuration. But Rails sees these two definitions as the same name at load time and throws the superclass error.
These are my thoughts about your question. I'm curious what you think.
When you are in production in Rails, the namespacing for controllers is far more strict. Rails expects the direct folder path. If you do not wish to do that then you should use scoping, for example:
scope :path => "account" do
resources :users
end
I switched from RSpec to Minitest recently. My model tests are all running great. However, my integration tests are no longer working.
None of my calls to have_content or have_selector are working.
I have included Capybara::DSL as follows in my test_helper.rb file:
class ActionDispatch::IntegrationTest
include Rails.application.routes.url_helpers # for x_path and x_url helpers
include Capybara::DSL
include PossibleJSDriver # switching Capybara driver for javascript tests
def setup
end
end
Here's the offending line in the test:
page.should have_selector('ul.ui-autocomplete li.ui-menu-item a')
and the error:
NoMethodError: undefined method `have_selector' for #<AppIntegrationTest:0x007f95f103afc8>
I don't understand why these don't work anymore. I am using the minitest-rails-capybara gem.
The syntax is different in Minitest. Use this instead:
page.must_have_selector('ul.ui-autocomplete li.ui-menu-item a')
Given the following code file (named server.go) in Go:
package glimpse
func SplitHeader() string {
return "hi there"
}
and the accompanying test file (server_test.go):
package glimpse
import (
"testing"
)
func TestSplitHeader(t *testing.T) {
answer := SplitHeader()
if answer == "" {
t.Error("No return value")
}
}
Why is it the following command:
go test server_test.go
returns
# command-line-arguments
./server_test.go:9: undefined: SplitHeader
I'm certainly missing something catastrophically obvious.
Use only
$ go test
from within the package directory to perform testing. If you name specific files as an argument to go test, then only those file will be considered for the build of the test binary. That explains the 'undefined' error.
As an alternative, use "import path" as an argument to go test instead, for example
$ go test foo.com/glimpse