2017-11-08 7 views
1

데이터베이스를 임의로 사용하는 NewDao 함수를 테스트 할 수 없습니다. 반환 된 Dao가 nil 클라이언트도 아니고 nil 제품도 아닌지 확인하고 싶습니다.오류를 반환하지 않기 위해 sqlmock을 스텁하는 방법은 무엇입니까?

type Dao struct { 
    client ClientDao 
    product ProductDao 
} 

func (d *Dao) Client() ClientDao { 
    return d.client 
} 

func (d *Dao) Product() ProductDao { 
    return d.product 
} 

func NewDao(db *sql.DB) (*Dao, error) { 
    if db == nil { 
    return nil, errors.New("Can't create a dao from nil database") 
    } 
    client, err := newClientDao(db) // Uses db arbitrarily 
    if err != nil { 
    return nil, err 
    } 
    product, err := newProductDao(db) // Uses db arbitrarily 
    if err != nil { 
    return nil, err 
    } 
    return &Dao{client, product}, nil 
} 

I의 sqlmock를 사용하여 테스트 NewDao()하지만 모의 필요가 무엇을 기대 모르기 때문에 항상 실패합니다.

func TestNewDao(t *testing.T) { 
    db, mock, err := sqlmock.New() 
    if err != nil { 
    t.Fatal("Can't create database for test dao") 
    } 

    // How to set mock to expect anything and never fail? 
    // mock.ExpectQuery(any) ? 

    dao, err := NewDao(db) 

    // err is never nil, because mock has no expectations 

    if err != nil { 
    t.Fatal("Can't create dao for test dao.User %q", err) 
    } 
    if dao.User() == nil { 
    t.Fatalf("User dao is nil") 
    } 
    if dao.Client() == nil { 
    t.Fatalf("Client dao is nil") 
    } 
} 

하나는 내 삶의 목적을 달성하기위한 sqlmock 스텁하는 방법을 알고 있나요? 또는 sqlmock lib에 대한 대안을 지정할 수 있습니까?

답변

1

당신은 NewDao에 마지막 대가로 두 번째 항목을 누락 :

return &Dao{client, product}

가 있어야한다 :

return &Dao{client, product}, nil

반환 문은 "반환"모든 일이에 선언해야 함수 헤더.

+0

의견을 보내 주셔서 감사합니다. 오류가 수정되었습니다. –

+0

내가 원하는 것은 임의로 db를 사용하는 UserDao 구현에 의존하지 않고 테스트를 수행하는 방법을 찾는 것입니다. –

0

Dao.ClientDao.Product 메쏘드는 메쏘드 자체가 어떤 의존성에 대해서도 호출하지 않기 때문에 아무 것도 모의 할 수 없습니다. 이 두 가지 방법을 테스트하기 위해 모의 (mock)를 사용할 필요는 없습니다.

그리고 이러한 라이너 하나를 테스트하는 것이 가장 현명한 방법이 아니지만, 테스트를 원할 경우 반환되는 값과 예상되는 필드의 값이 같아야합니다. 돌려 주다.

func TestDaoClient(t *testing.T) { 
    var client ClientDao // TODO: prepare a client dao value for test 

    tests := []struct{ 
     name string 
     dao *Dao 
     want ClientDao 
    }{{ 
     name: "should return client dao", 
     dao: &Dao{client: client}, 
     want: client, 
    }, { 
     name: "should return nil", 
     dao: &Dao{client: nil}, 
     want: nil, 
    }} 

    for _, tt := range tests { 
     t.Run(tt.name, func(t *testing.T) { 
      if got := tt.dao.Client(); !reflect.DeepEqual(got, tt.want) { 
       t.Errorf("client got=%v, want=%v", got, tt.want) 
      } 
     })  
    } 
} 

이제 Dao.Product 방법에 대해서도 동일하게 적용 할 수 있습니다.

+0

알았습니다! 감사! newClientDao (db) 함수를 사용하여 클라이언트를 만들어이 테스트를 수행 할 필요가 없습니다. 나는 내 질문에 나쁜 모범을 보였다. –

+0

방금 ​​예를 편집했습니다. 나는 그것이 도움이되기를 바랍니다. –