首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何测试服务或正确地模拟服务?Java11、Spock框架

如何测试服务或正确地模拟服务?Java11、Spock框架
EN

Stack Overflow用户
提问于 2022-01-22 21:31:38
回答 1查看 243关注 0票数 -1

各位同事,欢迎大家!告诉我如何决定,或如何行动。(Java11,SpringBoot,)我需要编写一个测试来测试一个类方法,整个问题是被测试类的方法通过继承调用另一个服务,这个服务不是在被测试的类中声明的,而是在它的抽象祖先中声明的。如何检验这样的故事?如果这个服务是在被测试的类中声明的,那么一切都是明确的,我将在测试中创建一个模拟,并将它传递给构造函数,但是如果这个服务位于祖先那里呢?我在下面附加一个示例代码。

代码语言:javascript
复制
// The class to be tested

@Service
public class ServiceForTest extends AbstractComponent{

    public String methodForTest (String s) {
        return someService.generateString(s);
    }

}

//An abstract class from which the tested one is inherited and which contains the service

public class AbstractComponent {

    @Autowired
    protected SomeService someService;

}

public interface SomeService {

    String generateString(String s);

}

@Service
public class SomeServiceImpl implements SomeService{

    @Override
    public String generateString(String s) {
        return s;
    }

}

下面是一个例子,说明如果服务在被测试的类中,我会做什么

代码语言:javascript
复制
//TestClass
@Service
public class ServiceForTest extends AbstractComponent{

    final SomeService someService;

    public ServiceForTest(SomeService someService) {
        this.someService = someService;
    }

    public String methodForTest (String s) {
        return someService.generateString(s);
    }

}

类测试groovy,Spock框架

代码语言:javascript
复制
class ServiceForTestTest extends Specification {

    ServiceForTest serviceForTest

    void setup(){
        SomeService someServiceMock = Mock(SomeService)
        someServiceMock.generateString("TEST") >> "TEST"
        serviceForTest = new ServiceForTest(someServiceMock)
    }

    def "Test for return current value"(){

        when:
        def methodForTest = serviceForTest.methodForTest("TEST")

        then:
        methodForTest == "TEST"

    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-23 03:31:18

您使用@Autowired,即某种依赖注入框架,如Spring或Java。这些框架具有测试支持。特别是对于Spring测试,Spock有一个可以使用的弹簧模块。我不是Spring用户,所以我不能告诉您如何做到这一点,但是文档非常好。

作为一般的答案,即使没有任何框架支持,如果您按照惯例将测试放入与被测试类相同的包中,则可以轻松地测试这一点。因为您想要将模拟注入的字段是protected,所以对于JVM来说,它意味着所有子类,以及同一个包中的其他类都可以访问它。也就是说,您可以简单地设置以下值:

代码语言:javascript
复制
serviceForTest = new ServiceForTest()
serviceForTest.someService = someServiceMock

或者,更优雅地使用Groovy风格的构造函数隐式设置字段值:

代码语言:javascript
复制
serviceForTest = new ServiceForTest(someService: someServiceMock)

通常,我推荐构造函数或setter注入,而不是依赖于字段注入(特别是当字段是私有的),因为在可测试性方面,您对DI框架有严格的依赖,并且无法轻松编写单元测试。所以如果你能重构,我建议你去做。您刚刚注意到,测试这样的东西可能会让人头疼,除非您有办法像在这个特殊情况下使用受保护的字段。但这并不是超级的重构友好。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70817315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档