如何改进此代码

Ula*_*kar 5 unit-testing scala scalatest

我正在尝试使用Scalatest为我的Java应用程序编写一些测试代码.我想,由于Scala具有更可读的语法,因此可以获得更易读的测试代码.

到目前为止,这是我管理的:

package com.xyz

import org.scalatest.FlatSpec
import org.scalatest.matchers.ShouldMatchers
import com.xyz.SecurityService
import org.mockito.Mockito._
import org.scalatest.mock.MockitoSugar
import org.mockito.Matchers._
import javax.servlet.jsp.tagext.Tag

class CheckRoleTagSpec extends FlatSpec with ShouldMatchers with  MockitoSugar {

  behavior of "CheckRole tag"

  it should "allow access when neither role nor root defined" in {
    val securityServiceMock = mock[SecurityService]

    val tag = new CheckRoleTag()
    tag.setSecurityService(securityServiceMock)

    tag.setGroup("group")
    tag.setPortal("portal")

    tag.setRoot(false)
    tag.setRole(null)

    tag.doStartTag should be(Tag.SKIP_BODY)
  }

}

我对这段代码感到非常失望.实际上,我需要用Java编写它.请帮助我使它更像scala和功能.

Jör*_*tag 9

你不能通过重写测试来修复丑陋的测试.您只能通过重新设计正在测试的API来修复它.

那么,在技术上,它可以写入良好的API丑陋的测试,如果你尝试真的很难,是非常邪恶的,非常愚蠢的,很醉酒或很疲惫.但是编写一个丑陋的测试需要付出努力,程序员也很懒惰,所以有人不太可能通过选择编写丑陋的测试.写丑陋的测试几乎是不可能的:你坚持下去,你得到一些东西,你检查你是否得到了你所期望的.而已.那里真的没什么可丑化的.

测试只是使用API​​,就像API的用户使用它一样.它基本上是一个如何正确使用API​​的示例,这也几乎是一个副作用,恰好检查API是否实际正确实现.这就是为什么丑陋的测试是错误的API设计的良好指标,这也是为什么测试驱动API设计是一件好事,即使你不做TDD也是如此.

在这种特殊情况下,我可以看到很多方法来改进API,尽管这些建议必然是不完整的,浅薄的和简单化的(更不用说可能是错误的),因为我对你的域名一无所知:

  • 更好的名字:setRoot听起来像是在设置根.但是,除非false是层次结构的根,否则我认为实际设置的是该标记是否为根.因此,它更应被命名为isRootmakeRootsetIsRoot或类似的东西.
  • 更好的默认值:继续setRoot,假设我的猜测正确并且设置标签是否是根,那么默认是错误的方式.根据"根"概念的定义,只能有一个根.所以,你强迫你的用户指定setRoot(false) 每一次,除了那一个时候,他们实际上是定义一个根.非根标签应该是默认的,你应该只能被迫setRoot(true)一个标签,它实际上根.
  • 更好的默认值,第二部分:setRole(null).真的吗?您是强制用户明确设置取消设置的角色?为什么不简单地取消默认设置?毕竟,测试被称为"...既没有角色也没有定义根",为什么要定义它们呢?
  • 流畅的API/Builder模式:如果你真的必须构造无效的对象(但参见下一点),至少要使用类似Fluent API或Builder模式的东西.
  • 仅构造有效对象:但实际上,对象在构造时应始终有效,完整且完全配置.您不必构造对象,然后对其进行配置.

那样,测试基本上变成:

package com.xyz

import org.scalatest.FlatSpec
import org.scalatest.matchers.ShouldMatchers
import com.xyz.SecurityService
import org.mockito.Mockito._
import org.scalatest.mock.MockitoSugar
import org.mockito.Matchers._
import javax.servlet.jsp.tagext.Tag

class CheckRoleTagSpec extends FlatSpec with ShouldMatchers with MockitoSugar {
  behavior of "CheckRole tag"
  it should "allow access when neither role nor root defined" in {
    val tag = new CheckRoleTag(mock[SecurityService], "group", "portal")

    tag.doStartTag should be(Tag.SKIP_BODY)
  }
}
Run Code Online (Sandbox Code Playgroud)


Vas*_*iuk 3

下面的代码创建新的匿名类,但doStartTag按预期返回结果:

...
(new CheckRoleTag{
   setSecurityService(mock[SecurityService])
   setGroup("group")
   setPortal("portal")
   setRoot(false)
   setRole(null)
} doStartTag) should be(Tag.SKIP_BODY)
...
Run Code Online (Sandbox Code Playgroud)