2016-02-09 3 views
0

Я застрял с модульным тестом в Скале в течение многих дней. Я не могу вводить макет объекта в модульный тест. ScalatraFlatSpec вызывает реальную базу данных, а не мою изменчивую переменную, и я не собираюсь ее делать.Scala Как вводить макет объекта в ScalatraFlatSpec

Это мой API

class Dashboard extends Servlet { 

    get("/:brand_code") { 
    val start = System.currentTimeMillis 
    val brandCode = params.get("brand_code").get 
    var brandId = 0; 
    val sqlFind = "SELECT DISTINCT(id) FROM brands WHERE brand_code=?" 
    val found:List[Map[String, Any]] = ConnectionModel.getExecuteQuery(sqlFind, List(brandCode)) 
    if(found.isEmpty){ 
     halt(404, send("error", s"brand_code [$brandCode] not found.")) 
    }else{ 
     brandId = found(0).getOrElse("id", 0).toString.toInt 

     send("Yeah55", brandId) 
    } 
} 

И это Servlet

abstract class Servlet extends ScalatraServlet with CorsSupport with  JacksonJsonSupport { 
    protected implicit lazy val jsonFormats: Formats =  DefaultFormats.withBigDecimal 
    protected override def transformResponseBody(body: JValue): JValue = body.underscoreKeys 

    protected lazy val body = parsedBody.extract[Map[String, Any]] 
    protected def send(message: String, data: Any = None) = Map("message" -> message, "data" -> data) 

    options("/*") { 
    response.setHeader(
     "Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers") 
    ) 
} 

before() { 
    contentType = formats("json") 
} 
} 

И это ConnectionModel и ConnectionModelAble

trait ConnectionModelAble { 
    def getExecuteQuery(sql: String, parameters: List[Any]): List[Map[String, Any]] 
} 

object ConnectionModel extends ConnectionModelAble{ 
    var connection:Connection = { 
    val url = "jdbc:mysql://localhost:3306/db" 
    val username = "root" 
    val password = ""\ 

    Class.forName("com.mysql.jdbc.Driver") 

    DriverManager.getConnection(url, username, password) 
    } 


def getExecuteQuery(sql: String, parameters: List[Any]): List[Map[String, Any]]= { 
    try { 
    val statement = connection.createStatement() 
    var preparedStatement: PreparedStatement = connection.prepareStatement(sql); 
    var formatDate: DateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 


    // Do some execute 
     for (i <- 0 until parameters.size) { 
    parameters(i) match { 
     case _: Int => preparedStatement.setInt(i + 1, parameters(i).toString.toInt) 
     case _: Double => preparedStatement.setDouble(i + 1, parameters(i).toString.toDouble) 
     case _: Date => preparedStatement.setDate(i + 1, new java.sql.Date(formatDate.parse(parameters(i).toString).getTime)) 
     case default => preparedStatement.setString(i + 1, parameters(i).toString) 
    } 
    } 

    val resultSet = preparedStatement.executeQuery() 

    val metaData: ResultSetMetaData = resultSet.getMetaData(); 
    val columnCount = metaData.getColumnCount(); 

    var ret: List[Map[String, Any]] = List(); 

    while (resultSet.next()) { 
    var row: Map[String, Any] = Map[String, Any](); 
    for (i <- 1 to columnCount) { 
     val columnName = metaData.getColumnName(i); 
     var obj = resultSet.getObject(i); 
     row += columnName -> obj 
    } 
    ret = ret :+ row 
    } 

    ret 

}catch { 
    case e: Exception => { 
    e.printStackTrace(); 
    List() 
    } 
} 

} 

И это мой блок тест

class DashboardSpec extends ScalatraFlatSpec with MockitoSugar { 

    addServlet(new Dashboard, "/v1/dashboard/*") 
     it should "return get dashboard correctly" in { 
     val brandCode = "APAAA" 
     val brandId = 157 

     get("/v1/dashboard/APAAA") { 
      val connectModel = mock[ConnectionModelAble] 

      val sqlFind = "SELECT DISTINCT(id) FROM brands WHERE brand_code=?" 
      Mockito.when(connectModel.getExecuteQuery(sqlFind, List(brandCode))).thenReturn(
    List(Map("id" -> 150)) 
) 
      assert(status == 200) 
      println(connectModel.getExecuteQuery(sqlFind, List(brandCode))) 
      println(body) 
     } 
    } 
} 

Я обнаружил, что тело из модульного теста не связано с моими издевательскими данными, это из реальной базы данных. Что мне делать.

спасибо.

ответ

1

Вы не инъекционные свой макет в Dashboard, так что Connection вы видите в getExecuteQuery это один обеспечивается ConnectionModel.connection. Вероятно, вы захотите использовать инфраструктуру инъекций зависимостей или что-то вроде шаблона Cake, чтобы ваша панель инструментов ссылалась на ваш макет.

+0

Большое спасибо. Я решил эту проблему путем изменений сервлета как этот класса Dashboard (дБ: ConnectionModelAble = ConnectionModel) продолжается Servlet { .... } так что я могу вводить фиктивное соединение, но я попробую торт шаблон. Огромное спасибо. –

Смежные вопросы