Как издеваться только над одним методом интерфейса - PullRequest
1 голос
/ 05 июля 2019

Я изо всех сил пытаюсь понять насмешки в Go (ищу что-то связанное с Mockito.spy эквивалентом Java в Go).

Допустим, у меня есть интерфейс в Go с 5 методами. Но фрагмент кода, который я хочу протестировать, содержит ссылки только на два метода. Теперь, как мне смоделировать эту зависимость без реализации всех методов, т.е. моя фактическая реализация в исходном коде реализует 5 методов интерфейса, но есть ли способ избежать реализации фиктивной реализации интерфейса 5 методов в тестовом файле. Ниже описан способ, которым я сейчас занимаюсь, реализация 5 методов - управляемая, но что, если в интерфейсе 20 методов, становится утомительно реализовывать все методы в тестовом файле.

Пример:

Исходный код в handler.go:

type Client struct {}
type ClientStore interface {
  func(c *Client) methodOne() error {// some implementation}
  func(c *Client) methodTwo() error {// some implementation}
  func(c *Client) methodThree() error {// some implementation}
  func(c *Client) methodFour() error {// some implementation}
  func(c *Client) methodFive() error {// some implementation}
}

Исходный код в api.go:

 func processFeed(c Client) error {
     err := c.methodOne()
     if(err != null) {
      return err
    }
     err1 := c.methodTwo()
     if(err1 != null) {
      return err1
    }
 }

Код класса теста:

import "testify/mock"

func TestFeed(t *testing.T){
   mockClient := &MockClient{}
   err := processFeed(mockClient)
   assert.NotNil(t , err)

}

type MockClient struct {
  mock.Mock
}

  func(c *MockClient ) methodOne() error {fmt.Printf("methodOne");nil}
  func(c *MockClient ) methodTwo() error {return errors.New("mocked error")}
  func(c *MockClient ) methodThree() error {fmt.Printf("methodThree");nil}
  func(c *MockClient ) methodFour() error {fmt.Printf("methodFour");nil}
  func(c *MockClient ) methodFive() error {fmt.Printf("methodFive");nil}


Вопрос:

Есть ли способ высмеивать только то, что мне требовалось, в приведенном выше случае только методы methodOne () и methodTwo () и не беспокоиться об оставшихся методах в тестах? Можете ли вы предложить какие-либо другие альтернативы, если они присутствуют? Спасибо

1 Ответ

3 голосов
/ 05 июля 2019

Во-первых, если ваш интерфейс имеет 5 методов, а вы используете только один, ваш интерфейс слишком велик.Используйте меньший интерфейс.

type BigInterface interface {
    Thing1()
    Thing2()
    ThingN()
}

type SmallInterface interface {
    Thing1()
}

func MyFunc(i SmallInterface) { ... }

Другой вариант заключается в создании полной реализации полного интерфейса путем встраивания полного интерфейса.Это вызовет панику, если вы попытаетесь получить доступ к одному из других методов, но будет работать для тестирования, если вы будете осторожны.(Но, пожалуйста, не делайте этого в рабочем коде!)

type BigInterface interface {
    Thing1()
    Thing2()
    ThingN()
}

type myImplementation struct {
    BigInterface
}

func (i *myImplementation) Thing1() { ... }

Теперь myImplementation удовлетворяет интерфейсу BigInterface, поскольку содержит встроенный экземпляр BigInterface.Если вы никогда не устанавливаете этот встроенный экземпляр на что-либо, тогда вызов этих методов вызовет панику, но вы все равно можете определить Thing1, чтобы делать то, что вы хотите для своих тестов.

...