[Закрываются] скрытые функции Ruby on Rails

Здесь я приведу пример тестового блока с вспомогательной функцией.

Контрольный пример: - вспомогательная функция Request_With_Query: - HttpReuqestSetup (путем mokcing HttprequestObject)

Я заметил, что издевался над объектом регистратора, так как он может помочь мне с предоставлением полезной информации

функция выглядит как

 public static class HttpTrigger
    {
        [FunctionName("HttpTrigger")]
        public async static Task<IActionResult> RunAsync([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequest req, TraceWriter log)
        {
            log.Info("C# HTTP trigger function processed a request.");

            string name = req.Query["name"];

            string requestBody = new StreamReader(req.Body).ReadToEnd();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            return name != null
                ? (ActionResult)new OkObjectResult($"Hello, {name}")
                : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
        }

    }

и вот так выглядит мой тестовый класс:

[TestClass]
    public class HttpTriggerTest : FunctionTestHelper.FunctionTest
    {
        [TestMethod]
        public async Task Request_With_Query()
        {
            var query = new Dictionary<String, StringValues>();
            query.TryAdd("name", "ushio");
            var body = "";

            var result = await HttpTrigger.RunAsync(req: HttpRequestSetup(query, body), log: log);
            var resultObject = (OkObjectResult)result;
            Assert.AreEqual("Hello, ushio", resultObject.Value);

        }

        [TestMethod]
        public async Task Request_Without_Query()
        {
            var query = new Dictionary<String, StringValues>();
            var body = "{\"name\":\"yamada\"}";

            var result = await HttpTrigger.RunAsync(HttpRequestSetup(query, body), log);
            var resultObject = (OkObjectResult)result;
            Assert.AreEqual("Hello, yamada", resultObject.Value);

        }

        [TestMethod]
        public async Task Request_Without_Query_And_Body()
        {
            var query = new Dictionary<String, StringValues>();
            var body = "";
            var result = await HttpTrigger.RunAsync(HttpRequestSetup(query, body), log);
            var resultObject = (BadRequestObjectResult)result;
            Assert.AreEqual("Please pass a name on the query string or in the request body", resultObject.Value);
        }
    }

Вот классы Helper

с использованием Microsoft.AspNetCore.Http; использование Microsoft.AspNetCore.Http.Internal; использование Microsoft.Azure.WebJobs; использование Microsoft.Azure.WebJobs.Host; использование Microsoft.Extensions.Primitives; используя Moq; используя Систему; using System.Collections.Generic; используя System.IO; используя System.Net.Http; используя System.Text; используя System.Threading; используя System.Threading.Tasks;

namespace FunctionTestHelper
{
    public abstract class FunctionTest
    {

        protected TraceWriter log = new VerboseDiagnosticsTraceWriter();

        public HttpRequest HttpRequestSetup(Dictionary<String, StringValues> query, string body)
        {
            var reqMock = new Mock<HttpRequest>();

            reqMock.Setup(req => req.Query).Returns(new QueryCollection(query));
            var stream = new MemoryStream();
            var writer = new StreamWriter(stream);
            writer.Write(body);
            writer.Flush();
            stream.Position = 0;
            reqMock.Setup(req => req.Body).Returns(stream);
            return reqMock.Object;
        }

    }

    public class AsyncCollector<T> : IAsyncCollector<T>
    {
        public readonly List<T> Items = new List<T>();

        public Task AddAsync(T item, CancellationToken cancellationToken = default(CancellationToken))
        {

            Items.Add(item);

            return Task.FromResult(true);
        }

        public Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            return Task.FromResult(true);
        }
    }
}

public class VerboseDiagnosticsTraceWriter : TraceWriter
    {

        public VerboseDiagnosticsTraceWriter() : base(TraceLevel.Verbose)
        {

        }
        public override void Trace(TraceEvent traceEvent)
        {
            Debug.WriteLine(traceEvent.Message);
        }
    }

Используйте подобный шаблон в вашем случае, вы должны быть в состоянии издеваться и писать UT мирно.

Надеюсь, это поможет.

57
задан 5 revs, 3 users 46% 23 May 2017 в 12:18
поделиться

13 ответов

Направляющие 2.3.x теперь позволяют Вам делать:

render @items

намного более простой..

8
ответ дан 2 revs, 2 users 89% 24 November 2019 в 19:13
поделиться

Я запущу с одного из своего избранного. При вызове частичного с набором, вместо цикличного выполнения через набор и вызове его для каждого объекта, можно использовать это:

render :partial => 'items', :collection => @items

Это назовет частичное однажды на объект и передаст объект локальной переменной каждый раз. Вы не должны волноваться о ноле, проверяющем @items также.

7
ответ дан Brian 24 November 2019 в 19:13
поделиться

integer.ordinalize - это один маленький метод, на который я недавно наткнулся.

1.ordinalize = "1st"
3.ordinalize = "3rd"
22
ответ дан Dan Frade 24 November 2019 в 19:13
поделиться

Если у вас есть модель с некоторыми методами класса и именованными областями действия:

class Animal < ActiveRecord::Base
  named_scope 'nocturnal', :conditions => {'nocturnal' => true}
  named_scope 'carnivorous', :conditions => {'vegetarian' => true}

  def self.feed_all_with(food)
    self.all.each do |animal|
      animal.feed_with(food)
    end
  end
end

Затем вы можете вызывать методы класса через именованную область действия:

if night_time?
  Animal.nocturnal.carnivorous.feed_all_with(bacon)
end
12
ответ дан 24 November 2019 в 19:13
поделиться

Если вы добавите маршрутизацию для ресурса:

ActionController::Routing::Routes.draw do |map|
  map.resources :maps
end

и зарегистрируете дополнительные типы MIME:

Mime::Type.register 'application/vnd.google-earth.kml+xml', :kml

Вам не нужен блок response_to в вашем контроллере для обслуживания эти дополнительные типы. Вместо этого просто создайте представления для определенных типов, например 'show.kml.builder' или 'index.kml.erb' . Rails будет отображать эти специфичные для типа шаблоны при получении запросов на '/ maps.kml' или '/ maps / 1.kml' , соответственно устанавливая тип ответа.

4
ответ дан 24 November 2019 в 19:13
поделиться

Вы можете воспользоваться тем, что определения классов Ruby активны и что Rails кэширует классы в производственной среде, чтобы гарантировать, что постоянные данные будут только извлекается из базы данных при запуске приложения.

Например, для модели, представляющей страны, вы должны определить константу, которая выполняет запрос Country.all при загрузке класса:

class Country < ActiveRecord::Base
  COUNTRIES = self.all
  .
  .
  .
end

Вы можете использовать эту константу в шаблоне представления (возможно, в помощнике выбора), обратившись к Country :: COUNTRIES . Например:

<%= select_tag(:country, options_for_select(Country::COUNTRIES)) %>
16
ответ дан 24 November 2019 в 19:13
поделиться

Чтобы просмотреть список установленных гемов, вы можете запустить:

gem server

Затем укажите в браузере:

http://localhost:8808

Вы получите хорошо отформатированный список ваших драгоценных камней со ссылками на rdoc, Интернет и любые другие зависимости. Намного лучше, чем:

gem list
18
ответ дан 24 November 2019 в 19:13
поделиться

в вашем environment.rb вы можете определить новые форматы даты / времени, например

[Time::DATE_FORMATS, Date::DATE_FORMATS].each do |obj|
  obj[:dots] = "%m.%d.%y"
end

, поэтому в ваших представлениях вы можете использовать:

Created: <%= @my_object.created_at.to_s(:dots) %>

, который будет напечатан следующим образом:

Created: 06.21.09
13
ответ дан 24 November 2019 в 19:13
поделиться

Чтобы избежать дублирования отправки форм, в Rails есть удобная опция для тегов отправки:

submit_tag "Submit", :disable_with => "Saving..."

Это добавляет поведение кнопке отправки, чтобы отключить ее после нажатия и отобразить «Сохранение ...» вместо «Отправить».

Rails 4+

 DEPRECATION WARNING: :disable_with option is deprecated and 
 will be removed from Rails 4.1. Use 'data: { disable_with: 'Text' }' instead.

Таким образом, приведенное выше становится:

submit_tag 'Submit', data: { disable_with: 'Text' }
70
ответ дан 24 November 2019 в 19:13
поделиться
ActionView::Base.default_form_builder = MyFormBuilderClass

Very useful when you're creating your own form builders. A much better alternative to manually passing :builder, either in your views or in your own custom_form_for helper.

1
ответ дан 24 November 2019 в 19:13
поделиться

В настоящее время мне нравятся div_for и content_tag_for

<% div_for(@comment) do %>
  <!-- code to display your comment -->
<% end %>

Приведенный выше код отображает это:

<div id="comment_123" class="comment">
  <!-- code to display your comment -->
</div>

Хотите, чтобы класс CSS был комментарий other_class ? Нет проблем:

<% div_for(@comment, :class => 'other_class') do %>
  <!-- code to display your comment -->
<% end %>

Хотите диапазон, а не div? Нет проблем, content_tag_for спешит на помощь!

<% content_tag_for(:span, @comment) do %>
<% end %>

# Becomes...

<span id="comment_123" class="comment">
  <!-- code to display your comment -->
</span>

content_tag_for также отлично подходит, если вы хотите использовать префикс id . Использую для загрузки гифок.

<% content_tag_for(:span, @comment, 'loading') do %>
  <%= image_tag 'loading.gif' -%>
<% end %>

# Becomes...

<span id="loading_comment_123" class="comment">
  <img src="loading.gif" />
</span>
21
ответ дан 24 November 2019 в 19:13
поделиться

The returning block is a great way to return values:

def returns_a_hash(id)
  returning Hash.new do |result|
   result["id"] = id
  end
end

Will return a hash. You can substitute any other types as well.

1
ответ дан 24 November 2019 в 19:13
поделиться

Вы можете изменить поведение модели для вашего набора тестов. Допустим, у вас есть определенный метод after_save, и вы не хотите, чтобы это происходило в ваших модульных тестах. Вот как это работает:

# models/person.rb
class Person < ActiveRecord::Base

  def after_save
    # do something useful
  end

end


# test/unit/person_test.rb
require 'test_helper'

class PersonTest < ActiveSupport::TestCase

  class ::Person
    def after_save
      # do nothing
    end
  end

  test "something interesting" do
    # ...
  end
end
5
ответ дан 24 November 2019 в 19:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: