2017-10-01 2 views
0

콘솔의 UI를 기반으로하고 case/when을 기반으로합니다. 나는 코드에 대해 몇 가지 rspec을 작성하려고한다. 이것은 내 코드 조각입니다.사용자 입력을 여러 번 시뮬레이트하는 방법

case choice 
when '1' #Create account 
    puts 'Enter username:' 
    username = gets.chomp 
    puts 'Enter Password' 
    password = gets.chomp 
    #createAccount() returns 1 or -1 after checking the database for duplicates 
    operation = System.createAccount(username, password) 
    if operation == -1 
    puts 'Error!' 
    else 
    puts 'Success!' 
    end 
when '2' #login case 
    #code omitted 
end 

나는 gets.chomp 작업을 완료해야합니다. 나는 과거를 얻을 allow 방법을 사용하여 같은 다양한 제안을 발견

STDIN.stub(:gets).and_return('name') 
STDIN.stub(:gets).and_return('password') 

을하지만 도움이되지 않았다; rspec 테스트를 실행해도 코드가 username = gets.chomp이되지 않습니다.

name과 그 이후의 password을 전달하도록 사양을 작성해야합니다 (작동 값이 1인지 테스트하고 싶습니다)?

+1

루비는 변수와 메소드 이름에 대한'snake_case' 명명 규칙, 즉'createAccount' 대신'create_account' 규칙을 강력히 권장합니다. 그 이유는 Ruby가 대소 문자를 구별하기 때문입니다. 대문자는 ClassName이나 CONSTANT와 같은 costants를 나타냅니다. – tadman

+1

또 다른 고려해야 할 점은 '-1'과 같은 오류 코드를 반환하는 것은 매우 C이며 매우 Ruby가 아니라는 것입니다. 생성 된 계정과 같은 객체를 반환하거나 예외를 throw하려고 할 수 있습니다. 이는 흐름 제어를 단순화하는 데 도움이됩니다. – tadman

답변

1

음, gets는 (혼합) 클래스를 포함 Kernel 모듈에 정의하는 방법이다, 그래서 당신은 이런 식으로 조롱 수 :

describe do 
    subject { described_class.new } 
    before do 
    allow(subject).to receive(:gets).and_return('name', 'password') 
    # https://relishapp.com/rspec/rspec-mocks/v/3-6/docs/configuring-responses/returning-a-value#specify-different-return-values-for-multiple-calls 
    end 

    specify do 
    expect(System).to receive(:createAccount).with('name', 'password') 
    subject.method_that_does_the_job 
    end 
end 

는 (나는 당신의 case choice... 코드가 내부 method_that_does_the_job입니다 가정)

일부 사람들은 조롱 된 테스트 객체를 코드 냄새라고 간주합니다 (그러나 설명하는 링크를 찾을 수는 없지만 어딘가에 읽었을 것입니다).