当前位置: 首页 > 知识库问答 >
问题:

单元测试:在父测试类中为被测试的单元生成mock

南门飞扬
2023-03-14

我目前正在与CDI Unit合作一个项目,我遇到了一个奇怪的问题。我试图在一个简单的项目中重现它:

我有一个使用CdiRunner运行的测试类(如下所述:http://jglue.org/cdi-unit-user-guide/我的测试类注入了被测试的单元:UUD。这个类扩展了一个超级类“ParentTestClass”,它目前是无用的。

测试课。爪哇:

package fr.perso.tutorial.cdiunit.test;

import javax.inject.Inject;

import org.jglue.cdiunit.CdiRunner;
import org.junit.Test;
import org.junit.runner.RunWith;

import fr.perso.tutorial.cdiunit.controller.UUD;

@RunWith(CdiRunner.class)
public class TestClass extends ParentTestClass {

    @Inject
    private UUD uud;

    @Produces
    @Mock
    private MyController myController;

    @Test
    public void test() {

    }
}

正如我提到的,父类是空的。

ParentTestClass。爪哇:

package fr.perso.tutorial.cdiunit.test;


public class ParentTestClass {

}

正如我们所见,被测单元需要MyController才能工作。这就是为什么我在测试课上制作了一个模拟。

乌德。爪哇:

package fr.perso.tutorial.cdiunit.controller;

import javax.inject.Inject;

import org.junit.Before;

public class UUD {

    @Inject
    private MyController myController;

    @Before
    private void initialize(){
        System.out.println("I'm the unit under test and i need this controller to work : " + myController.toString());
    }
}

我的控制者。爪哇:

package fr.perso.tutorial.cdiunit.controller;

public class MyController {

    @Override
    public String toString() {
        return "[controller : " + super.toString() + "]";
    }
}

好的,问题是:当我们在测试类中声明模拟时,测试是可以的。但是如果我在父母测试类中声明它,我们会有以下错误:

org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type MyController with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject private fr.perso.tutorial.cdiunit.controller.UUD.myController
  at fr.perso.tutorial.cdiunit.controller.UUD.myController(UUD.java:0)
  Possible dependencies:
  - Producer Field [MyController] with qualifiers [@Any @Default] declared as [[UnbackedAnnotatedField] @Produces @Mock private fr.perso.tutorial.cdiunit.test.TestClass.myController],
  - Managed Bean [class fr.perso.tutorial.cdiunit.controller.MyController] with qualifiers [@Any @Default],
  - Producer Field [MyController] with qualifiers [@Any @Default] declared as [[BackedAnnotatedField] @Produces @Mock private fr.perso.tutorial.cdiunit.test.ParentTestClass.myController]

    at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:367)
    at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:281)
    at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
    at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155)
    at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518)
    at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68)
    at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:60)
    at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:53)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

我希望在超类中创建mock,以便在我的项目中复制代码。我知道有些人认为使用超级测试类是一种代码气味(例如:https://www.petrikainulainen.net/programming/unit-testing/3-reasons-why-we-should-not-use-inheritance-in-our-tests/)

即使我不完全同意这篇文章(我可能是错的),它也不能解释为什么在超类中创建mock时会出现模糊依赖性问题。

有人知道为什么会出现这个问题,并且知道如何解决它,除了在一个类中编写所有代码吗?

非常感谢你的帮助!

共有1个答案

高祺
2023-03-14

我无意中发现了同样的事情。答案在这里:https://stackoverflow.com/a/32985745/6324171

当您试图在抽象类或父类中生成时,它不起作用,因为@products不会被继承。

我把我的模拟制作人换到了另一个班级(正如另一个答案所建议的那样),结果一切如期。

不过,我不得不在getter上使用@Produces:

public class DateAndTimeMasterForTestProducer {

    @Produces
    @ApplicationScoped
    public DateAndTimeMaster getDateAndTimeMaster() {
        return mock(DateAndTimeMasterImpl.class);
    }

}

不幸的是,我无法使用Mockito和field producer的@Mock注释。

 类似资料:
  • Android Studio 1.1 添加了单元测试支持,详细请看 Unit testing support。本章的其余部分描述的是 “instrumentation tests”。利用 Instrumentation 测试框架可以构建独立的测试 APK 并运行在真实设备(或模拟器)中进行测试。

  • 英文原文:http://emberjs.com/guides/testing/unit/ 单元测试用于测试代码的一个小片段,确保其功能正常。与集成测试不同,单元测试被限定在一个范围内,并且不需要Ember应用运行。 全局 vs 模块 过去如果没有作为一个全局变量加载整个Ember应用,要对应用进行测试非常困难。通过使用模块(CommonJS,AMD等)来编写应用,可以只加载被测试的部分,而不用将其

  • 单元测试 单元测试仅依赖于源代码,是测试代码逻辑是否符合预期的最简单方法。 运行所有的单元测试 make test 仅测试指定的package # 单个package make test WHAT=./pkg/api # 多个packages make test WHAT=./pkg/{api,kubelet} 或者,也可以直接用go test go test -v k8s.io/kubernet

  • 单元测试是一种用于测试应用程序中每个函数的软件开发方法。如果你对此概念不熟悉,或许需要google一下相关概念。 CodeIgniter的单元测试类非常简单,由一个评估函数和两个结果函数组成。它没打算成为一个十全的测试集,只提供一个简单的能够评测你的代码是否可以产生正确的数据类型及结果的解决方案。 初始化单元类 和大多数其它的类一样,在CodeIgniter中,单元测试类一样要在控制器中用函数$t

  • 单元测试是一种为你的应用程序中的每个函数编写测试的软件开发方法。如果你还不熟悉这个概念, 你应该先去 Google 一下。 CodeIgniter 的单元测试类非常简单,由一个测试方法和两个显示结果的方法组成。 它没打算成为一个完整的测试套件,只是提供一个简单的机制来测试你的代码是否 生成了正确的数据类型和结果。 使用单元测试类库 初始化类 运行测试 生成报告 严格模式 启用/禁用单元测试 单元测

  • 单元测试涉及测试软件应用程序的每个单元或单个组件。这是第一级软件测试。单元测试的目的是验证单元组件的性能。 单元是软件系统的单个可测试部分,并在应用程序软件的开发阶段进行测试。 此测试旨在测试隔离代码的正确性。单元组件是应用程序的单独功能或代码。白盒测试方法用于单元测试,通常由开发人员完成。 在测试级别层次结构中,单元测试是在集成和其他剩余测试级别之前完成的第一级测试。它使用模块进行测试,减少了等