2013-06-30 3 views
0

я следующий метод в игре я развиваю:RSpec тестирование `` rand` внутри rand`

def search 
    if rand(5) == 0 
     weapon = Weapon.offset(rand(Weapon.count)).first 
     users_weapon = UsersWeapon.create(user_id: self.id, weapon_id: weapon.id, ammo: weapon.max_ammo) 
     self.users_weapons << users_weapon 
     { :success => 'true', :weapon => users_weapon } 
    else 
     { :success => 'false' } 
    end 
    end 

Как вы можете видеть, у меня есть два rand «S есть.
Теперь, когда я пытаюсь проверить его с RSpec, я хочу, чтобы проверить следующее его:

context 'when searches location' do 
    subject(:user) { FactoryGirl.create :User } 
    before { FactoryGirl.create :knife } 
    before { FactoryGirl.create :pistol } 

    context 'when finds knife' do 
    before { srand(2) } 
    it { user.search[:weapon].weapon.name.should == 'Knife' } 
    end 

    context 'when finds pistol' do 
    before { srand(3) } 
    it { p user.search[:weapon][:name].should == 'Pistol' } 
    end 

Независимо от того, что я прохожу в srand здесь, он работает только в одном из двух способов:
a) возвращает Pistol
OR
б) возвращает ноль.

Я хочу заглушить эти rand s независимо. Я не хочу посеять только один weapon в каждом контексте, потому что я хочу на самом деле проверить выбор случайного оружия. Как я могу это сделать?

+0

Какие утверждения вы хотели бы рассказать о своем случайном выборе оружия? То есть что это за их поведение, которое вы хотите продемонстрировать и потенциально поддерживаете? Если вы хотите что-то утверждать о самой случайности, это другая проблема, когда вы хотите что-то сказать о том, что происходит, когда каждый путь кода реализуется. –

ответ

0

почти все rand() являются случайными генераторами psuedo, их случайность зависит от семени, с которого вы их начинаете, прекратите посев с тем же номером, вместо этого используйте что-то вроде времени (srand(gettime())) или что-то, что меняется каждый раз.

PS: gettime() должен возвращать Int, вам придется сделать обертку для какой нормальной функции времени Руби возвращается, чтобы преобразовать его в ИНТ

2

использование целью выявления имя для метода, то высмеивать этот метод вместо рандов

def search 
    if rand(5) == 0 
    weapon = Weapon.find_random 
    # ... 

class Weapon 
    # ... 
    def self.find_random 
    self.offset(rand(self.count)).first 

Теперь вы можете легко издеваться Weapon.find_random

И при желании легко изменить реализацию позже

class Weapon 
    # ... 
    def self.find_random 
    # postgres 
    self.order("RANDOM()").limit(1).first 
    # mysql 
    self.order("RAND()").limit(1).first