2009-06-12 3 views
23

팩토리 걸은 테스트 용 모델 인스턴스를 쉽게 만들 수있는 편리한 프레임 워크입니다. Factory Girl home page에서Factory Girl과 같은 프레임 워크가 Java에 있습니까?

:

factory_girl가 신속하게 각 모델에 대한 프로토 타입을 정의하고 손에서 테스트의 중요한 속성 인스턴스를 요청 할 수 있습니다.

(홈 페이지도) 예 : 나는 사용자가 필요한 경우

Factory.sequence :email do |n| 
    "somebody#{n}@example.com" 
end 

# Let's define a factory for the User model. The class name is guessed from the 
# factory name. 
Factory.define :user do |f| 
    # These properties are set statically, and are evaluated when the factory is 
    # defined. 
    f.first_name 'John' 
    f.last_name 'Doe' 
    f.admin  false 
    # This property is set "lazily." The block will be called whenever an 
    # instance is generated, and the return value of the block is used as the 
    # value for the attribute. 
    f.email  { Factory.next(:email) } 
end 

A는 단지

test_user = Factory(:user, :admin => true) 

를 호출 할 수 있습니다에 지정된 모든 속성을 가진 사용자를 얻을 것입니다 공장 프로토 타입 (명시 적으로 지정한 admin 속성의 경우 제외) 또한 전자 메일 팩터 리 메서드는 호출 될 때마다 다른 전자 메일을 생성합니다.

나는 Java와 비슷한 것을 구현하는 것이 꽤 쉬워야한다고 생각하지만 휠을 재발 명하고 싶지는 않습니다.

P.S : JMock과 EasyMoc에 대해 알고 있지만, 여기서 조롱하는 프레임 워크에 대해서는 언급하지 않았습니다.

+0

FactoryGirl에 대한 예를 들려 주시겠습니까? 다른 곳으로 가서 읽지 않아도됩니까? – skaffman

+1

그 frameworker의 권리 조합이 그 길에서 점점 더 시작될 때까지 파이썬에 대한 것이있었습니다! –

+0

Beanmother https://github.com/keepcosmos/beanmother가 원하는 것입니다. –

답변

5

이 작업을 수행 할 수있는 라이브러리는 Usurper입니다.

그러나 작성중인 오브젝트의 특성을 지정하려는 경우 Java의 정적 유형 지정은 프레임 워크를 무의미하게 만듭니다. 프레임 워크가 reflection이나 Java Bean 인트로 스펙을 사용하여 속성 접근자를 찾을 수 있도록 속성 이름을 문자열로 지정해야합니다. 그러면 리팩토링이 훨씬 어려워집니다.

개체를 새로 고치고 메서드를 호출하는 것이 훨씬 간단합니다. 테스트에서 많은 상용구 코드가 발생하지 않도록하려면 Test Data Builder 패턴이 도움이 될 수 있습니다.

+0

글쎄 - 내 질문이 있다면이 대답을 받아 들일 것입니다. :) – cwash

+1

[쉽게 만들기] (http://code.google.com/p/make-it-easy/)는 각 속성의 기본값을 정의하는 테스트 데이터 빌더를 구현하는 데 도움이되므로 어떻게 든 유사합니다. – Augusto

+0

위탁 링크가 끊어져 프로젝트가 죽은 것으로 보입니다. –

-1

모델 개체가 단순한 경우 프레임 워크를 사용하여 모델 개체를 만드는 이유가 없으므로 'new'연산자 만 사용하면됩니다. 복잡한 모델 (복잡한 관계)가있는 경우 다음이 둘을 결합하는 스프링을 사용할 수 있습니다 (심지어 테스트 시나리오에서 사용할 수있는 봄)

  • 하지만 당신은 객체를 인스턴스화에 대해 이야기하는 경우이 데이터 개체에 대한 간단 그것들은 실제 인스턴스를 사용하는 대신 외부 관계를 조롱하거나 스터핑하는 것이 좋습니다.
+0

"모델 개체가 단순한 경우" 그들은 다음과 같지 않습니다 .-) "봄을 사용하여 함께 묶을 수 있습니다." 조금 더 자세히 설명해 주시겠습니까? 영화 모델이 있고 영화에 여러 개의 스트림이 있고 각 스트림에 호스트가 있다고 가정 해 보겠습니다. 이제 테스트 목적으로 25 개의 영화를 원합니다. 스프링이 나를 어떻게 도와 주나요? 내 파인더 메도우를 테스트하기 위해 데이터베이스에 25 개의 영화가 필요한 경우 어떻게해야합니까? – KaptajnKold

+0

어떤 복잡한 객체에 대해서도 'new'키워드를 사용하여 빌드하려고하지 않는 것이 좋습니다. 최소한 Object Mother 패턴 (일반적으로 초기화 된 객체에 대한 정적 팩토리 메소드 생성)을 사용하고 싶습니다. 그러나 빌더 패턴을 사용하는 것이 좋습니다. 이는 기본 설정과 세밀한 수준에서 속성을 무시하는 메커니즘을 제공하기 때문입니다. – cwash

+0

여기에 너무 많은 것들이 섞여 있다고 생각합니다. - 데이터베이스 코드 테스트의 경우 데이터베이스 사전/사후 테스트를 관리하는 데 도움이되는 DBUnit이 있습니다. - 유닛 테스트의 경우 영화 25 장이 필요하지 않으며, 2 광석 3은 UNIT 테스트에 충분합니다. 내 의견은 ... 테스트를 단순화하려고 시도하면 테스트를위한 입력을 작성하는 데 프레임 워크가 필요하지 않음을 알 수 있습니다. – silmx

2
  1. 나는이 모두를 위해 아닙니다 이해하지만 당신은 자바 코드에 루비 테스트 코드를 작성할 수 있습니다. (JTestR)
  2. Java에서이 작업을 수행하는 가장 좋은 방법은 Test Data Builder 패턴을 사용하는 것입니다. 나는이 접근법이 프레임 워크 또는 외부 의존성의 복잡성을 도입하는 것을 정말로 보증하지 않는다고 주장 할 것이다. 프레임 워크를 사용하여 더 적은 것을 지정할 수있는 방법을 알지 못하고 그 이상을 얻는 방법을 모르겠습니다 ... 빌더 구문은 기본적으로 FactoryGirl 구문과 동일합니다. (누군가가 다른 날 설득 주시기 바랍니다!)
1

을 나는 이것이 당신이 ...

찾고있는 정확하게 아니라는 것을 알고 난 반사를 사용하는 것은 채울 것을 나는 몇 가지 코드를 작성했습니다 과거 콩 값. 기본 아이디어는 모든 세터를 찾아 더미 값으로 호출하는 것입니다. 내 버전은 setName 필드의 이름으로 모든 문자열을 "name"으로 호출 한 다음 모든 int를 1로 설정하고 부울을 true로 설정합니다.

그런 다음이를 Object mother와 유사한 패턴과 함께 사용했습니다. 테스트 데이터 빌더.

테스트 데이터에 대한 좋은 시작을 제공하고 특정 값을 필요로하는 필드는 테스트의 일부로 명시 적으로 설정할 수 있습니다.

희망이 도움이됩니다.

19

나는 또한 Factory Girl의 Java 동등 물을 찾았지만 비슷한 것을 찾지 못했습니다. 대신 처음부터 솔루션을 만들었습니다. Java로 모델을 생성하는 팩토리 : Model Citizen. 공장 소녀에서 영감을

, 그것은 a simple example from the wiki, 모델에 대한 기본값을 설정하는 필드 주석을 사용

@Blueprint(Car.class) 
public class CarBlueprint { 

    @Default 
    String make = "car make"; 

    @Default 
    String manufacturer = "car manufacturer"; 

    @Default 
    Integer mileage = 100; 

    @Default 
    Map status = new HashMap(); 
} 

이 자동차 모델에 대한 청사진이 될 것입니다. 새로운 인스턴스가 생성 될 수있는 것보다 다음과 같이는 ModelFactory에 등록되어

ModelFactory modelFactory = new ModelFactory(); 
modelFactory.registerBlueprint(CarBlueprint.class); 
Car car = modelFactory.createModel(Car.class); 

당신은 대신 클래스의 자동차의 인스턴스를 전달하고 값을 설정하여 자동차 모델의 값을 재정의 할 수 있습니다 필요에 따라 :

Car car = new Car(); 
car.setMake("mustang"); 
car = modelFactory.createModel(car); 

wiki은 몇 가지 더 종과 경적을 위해 더 복잡한 예 (such as using @Mapped) 및 세부 사항이 있습니다.

1

같은 질문으로 여기에 도착했으며 통합 테스트를 위해 데이터 생성 도구에 필요했습니다. Groovy로 도전을 받아들이기로 결정했습니다. Groovy는 컴팩트하고 power assert이기 때문에 테스트를 위해 선택한 언어입니다.

저는 방금 아래와 같이 데이터 스크립트를 작성할 수있는 작은 도우꾼 https://gist.github.com/pgaertig/9502960 (FactoryGrill;)을 작성했습니다. 당신은 그루비로 더 많은 작업을 수행 할 수 있습니다

INSERT INTO MyTable(ID, CREATED_AT, NAME) VALUES (1, ..current date here.., 'Example text') 

: 위의

insert('MyTable', ID: 1, CREATED_AT: new Date(), NAME: 'Example text') 

는 것과 같습니다

import org.apache.commons.lang3.RandomStringUtils; 

for (i in 0..9) { 
    insert('USERS', CREATED_AT: new Date(), EMAIL: "test${i}@mydomain.com", 
        SALT: RandomStringUtils.randomAlphanumeric(32)); 
} 

load(new File('usersettings.groovy').text) //script nesting etc 

그것은 공장 아닌 정말 때문에 공장 매우 정직하고 그루비에서 map constructor 또는 expandos에 있습니다 .

위의 내용은 ~ 30LOC로만 달성되었으므로 FactoryGirl의 참고 자료 및 기타 자료는 현재 제공되지 않습니다. 그러나 내 솔루션에 관심이 있다면 Github에 전용 프로젝트를 추가 할 것입니다.

관련 문제