2016-02-20 3 views
0

Я использую scalatest вместе с scalamock для моего небольшого проекта. Я создал черту и класс вместе со своим сопутствующим объектом.Scala - Есть ли способ издеваться над чертой, расширенной сопутствующим объектом?

trait A{ 
def getSomething(arg1) 
} 

class B(field1).... 

object B extends A{ 
def apply(arg1) = new B(getSomething(arg1)) 
} 

Код работает отлично, но проблема возникает при тестировании этого кода. Юнит-тестирование должно быть зависимы друг от друга, поэтому я должен как-то издеваться/заглушкой черта A:

val fakeA = stub[A]  
(fakeA.getSomething _).when(arg).returns(res) 

А теперь ... Как я должен использовать эту высмеивал черту в моей модульного тестирования? Mocking создает объект (а не тип), и с таким кодом я не могу «передать его» моему объекту (или использовать с). Как я могу достичь своей цели (заглушить/mock getSomething() внутри моего объекта B)? Я попытался разделить объект B на Blogic и B, расширяющий Blogic. Но что тогда?

+0

Какую логику вы на самом деле пытаетесь проверить здесь? Кто использует насмешливый метод? – Dima

+0

Изделенный метод будет использоваться в моем модульном тесте. Здесь я хотел бы проверить, применит ли метод apply действительный объект (т. Е. Он присваивает правильные значения (возвращаемые методом Im, пытающимся имитировать) в соответствующие поля моего класса B. – DorianOlympia

+0

Просто выполните 'new B (whateverYourMockWouldReturn)' then и испытайте это. – Dima

ответ

0

Объект в Скале - это единичные экземпляры, что означает «конец света». Они не могут быть унаследованы, издеваются (без хаков) или что-то еще. У вас есть следующие варианты:

  1. Проверьте свой объект напрямую, т.е. вызовите B.apply(...) и проверьте результат на ожидаемый результат.
  2. Extract функциональность объекта по отношению к характеристикам/классов, и пусть он просто смешать все функциональные возможности вместе

Пример 2-го раствора

trait A{ 
    def getSomething(arg1: Int): Int = ??? 
} 

trait BFactoryUsingA { self: A => // This says that it needs/requires A 
    def apply(arg1: Int) = new B(getSomething(arg1)) 
} 

class B(field1: Int) {} 

object B extends BFactoryUsingA with A { 
    // No methods or those which have nothing to do with traits A and BFactoryUsingA hierarchy and composition 
} 

В вы тестируете теперь вы можете написать:

// Instance as anonymous mixin of traits containing logic 
val instanceUnderTest = new BFactoryUnsingA with A { } 

Я не могу сказать, если у вас есть способность и роскошь рассекать ваш объект на черты. Большую часть времени это выполнимо без чрезмерных хлопот, но ваш пробег может отличаться. Другим преимуществом такого решения вовсе не является необходимость в издевательствах.

Надеюсь, это поможет