Java 如何模拟Spring应用程序上下文';使用Mockito编写带有TestNG的单元测试的getBean方法?

Java 如何模拟Spring应用程序上下文';使用Mockito编写带有TestNG的单元测试的getBean方法?,java,spring,mockito,testng,Java,Spring,Mockito,Testng,我正在为下面的课程编写单元测试 待测类别: public class RandomManager { @Autowired private ApplicationContext context; @Autowired private ClassA objectA; public void methodToBeTested() { objectA.methodToBeVerified(con

我正在为下面的课程编写单元测试

待测类别:

public class RandomManager {
        @Autowired
        private ApplicationContext context;

        @Autowired
        private ClassA objectA;

        public void methodToBeTested() {
            objectA.methodToBeVerified(context.getBean(Random.class,"Yaswanth","Yaswanth"));
        }
    }
以下是测试等级:

public class RandomManagerTest {

    @Mock
    private ClassA objectA;

    @Mock
    private ApplicationContext context;

    @InjectMocks
    private RandomManager randomManager;

    @BeforeTest
    public void before() {
        MockitoAnnotations.initMocks(this);
        doReturn(any(Random.class)).when(context)
            .getBean(any(Class.class), any(), any());
    }

    @Test
    public void methodToBeTestedTest() {
        Random randomObject = new RandomObject("Yaswanth", "Yaswanth");
        randomManager.methodToBeTested();
        verify(objectA).methodToBeVerified(randomObject);
    }
}
当我尝试存根时,上述代码在before方法中失败 应用上下文模拟。我得到以下错误

不能在验证或存根之外使用参数匹配器。 正确使用参数匹配器的示例: when(mock.get(anyInt()).thenReturn(null); doThrow(newruntimeexception()).when(mock).someVoidMethod(anyObject()); 验证(mock).someMethod(包含(“foo”))

如果最后一次出现NullPointerException,则此消息可能出现在NullPointerException之后 matcher像any()一样返回一个对象,但不是stubbed方法 签名需要一个基元参数,在本例中,使用基元 选择。 当(mock.get(any());//使用不当,将提高NPE 当(mock.get(anyInt());//正确使用

此外,此错误可能会出现,因为您将参数匹配器用于 无法模拟的方法。不能使用以下方法 存根/验证:final/private/equals()/hashCode()。模拟方法 不支持在非公共父类上声明

有谁能帮我理解我在这个世界上做错了什么 以上代码

注意:我使用的是TestNG和Mockito。我可以延长
AbstractTestNGSpringContextTests
并使用
spring test.xml
,声明我的 beans和autowire应用程序上下文。我觉得这对我来说太过分了
我的用例。我只需要模拟applicationContext的getBean方法。

问题来自
doReturn(any(Random.class))
不允许使用
any()

只需将其替换为真实实例。

对于格式设置,我深表歉意。由于某种奇怪的原因,我无法提交这个问题。我真的不明白为什么要在基于Spring的测试中模拟任何东西(除了使用MockMVC的http层)。当您使用
@RunWith(SpringJUnit4ClassRunner.class)
时,您可以加载所有Springbean,它们将连接在一起,您可以测试实际的代码,而不是返回测试中定义的内容的存根,并且永远不会在依赖bean中实际执行代码。如果使用得当,Mocking是一个很好的工具,但我从未在基于Spring的测试中使用过它,当我看到其他人这样做时,它总是一团糟。我认为@KlausGroenbaek是正确的。与其试图模仿Spring应用程序上下文,不如使用它。创建一个测试应用程序上下文,返回测试所需的适当bean/mock。@KlausGroenbaek
@RunWith
不适用于TestNG,应该使用
AbstractTestNGSpringContextTests
。没错,我忘了它是TestNG。我更喜欢JUnit和Spring,因为它集成得更好。尽管有一些特性,比如参数化测试,在TestNG中更容易实现。两者之间有一个范例差异,因为每个JUnit测试都在测试类的一个新实例上运行,其中TestNG对多个测试重用同一实例,因此如果使用局部变量,必须小心。谢谢@juherr。成功了。但是为什么我们不应该在doReturn()中使用any()?我想是因为any*id用于参数匹配,而不是用于返回的参数。事实上,解决方案就在错误消息中。但也许你想要的是可能的(一个很好的新问题)