模拟类特定的方法(其余应该是真实的)

发布于 2025-02-13 15:28:27 字数 737 浏览 2 评论 0原文

我有一个要测试的课程,还可以嘲笑一种特定的方法。 我创建了一个间谍,如下所示:

recertialssservice partialMock = spy(recertialssservice.class);

并在我的测试中调用我要测试的方法: partialmock.process(客户端,ID,URL,NULL,userDetails);

在真实方法中:

@Autowired private Encryptionservice engryptionservice; 我的休息在NullPoInterException上失败了,因为该类的自动病毒之一是null。 在此行中:

Credential credentials = new Credential(id, encryptionService, tokenResponseParams.getAccessToken(), tokenResponseParams.getRefreshToken(), tokenResponseParams.getExpiresIn());
 

Encryptionservice是null,并且创建凭据类的操作之一是对此失败的。

任何知道为什么我的间谍不将gentionservice作为bean的真实实例以及如何解决?

I have a class that I want to test, and also mock a specific method.
I've created a spy as follows:

CredentialsService partialMock = spy(CredentialsService.class);

And call in my test to a method I want to test:
partialMock.process(client, id, url, null, userDetails);

In real method:

@Autowired private EncryptionService encryptionService;
My rest fails on NullPointerException, because one of the autowires of the class is NULL.
In this line:

Credential credentials = new Credential(id, encryptionService, tokenResponseParams.getAccessToken(), tokenResponseParams.getRefreshToken(), tokenResponseParams.getExpiresIn());
 

encryptionService is null and one of the operation in creating the Credential class fail on this.

Any idea why my spy does not keep the real instance of encryptionService as a bean, and how I can fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

别靠近我心 2025-02-20 15:28:27

您仅在spy()方法中仅使用类参数创建间谍,因此Mockito不知道应该注入创建的间谍对象中的任何对象。

要注入丢失的依赖关系,您可以选择三种方法之一(一种无需修改实际代码)。为了简化,在示例中,我剥离了对象,因为没有提供完整的代码。


让我们首先假设现场注射(这更多地介绍了为什么它会觉醒要使用现场注入):

class EncryptionService {

    void encrypt() {
        System.out.println("Encrypted!");
    }
}

class CredentialsService {

    EncryptionService encryptionService;

    void process() {
        encryptionService.encrypt();
    }
}

注释

@Mock // or @Spy, or actual object
EncryptionService encryptionService;
@Spy
@InjectMocks // this tells Mockito to inject dependencies
CredentialsService credentialsService;

@BeforeEach
void setUp() {
    // here the injection actually happens
    // openMocks() in more recent versions of Mockito
    MockitoAnnotations.initMocks(this);
}

@Test
void annotationInjection() {
    credentialsService.process();
}

对于下面的两种方法,我们都需要将依赖项注入构造函数,因此recertentialsservice看起来像这样:

class CredentialsService {

    EncryptionService encryptionService;

    CredentialsService(EncryptionService encryptionService) {
        this.encryptionService = encryptionService;
    }

    void process() {
        encryptionService.encrypt();
    }
}

模拟设置

@Test
void mockWithSettings() {
    var credentialsService = mock(CredentialsService.class, withSettings()
            // EncryptionService could be also a mock or a spy
            .useConstructor(new EncryptionService())
            // actually acts like a spy thanks to the below setting
            .defaultAnswer(CALLS_REAL_METHODS));
    
    credentialsService.process();
}

在对象上读取更多信息


spy

@Test
void spyOnObject() {
    var encryptionService = mock(EncryptionService.class);
    var credentialsService = spy(new CredentialsService(encryptionService));

    credentialsService.process();
}

我通常使用上述方法中的第一个或最后一个方法(但第一个使用构造函数注入依赖项的方法 -它也起作用)。

You are creating a spy using only a class parameter in the spy() method, so Mockito does not know about any object that should be injected into the created spy object.

To inject the missing dependency you can pick one of three approaches (one without modification of the actual code). For the sake of simplification in the example I've stripped the objects as complete code was not provided.


Let's assume field injection first (here's more on why it's discouraged to use field injection):

class EncryptionService {

    void encrypt() {
        System.out.println("Encrypted!");
    }
}

class CredentialsService {

    EncryptionService encryptionService;

    void process() {
        encryptionService.encrypt();
    }
}

Annotations

@Mock // or @Spy, or actual object
EncryptionService encryptionService;
@Spy
@InjectMocks // this tells Mockito to inject dependencies
CredentialsService credentialsService;

@BeforeEach
void setUp() {
    // here the injection actually happens
    // openMocks() in more recent versions of Mockito
    MockitoAnnotations.initMocks(this);
}

@Test
void annotationInjection() {
    credentialsService.process();
}

For both approaches below we will need the dependencies to be injected in a constructor, so CredentialsService looks like this:

class CredentialsService {

    EncryptionService encryptionService;

    CredentialsService(EncryptionService encryptionService) {
        this.encryptionService = encryptionService;
    }

    void process() {
        encryptionService.encrypt();
    }
}

Mock settings

@Test
void mockWithSettings() {
    var credentialsService = mock(CredentialsService.class, withSettings()
            // EncryptionService could be also a mock or a spy
            .useConstructor(new EncryptionService())
            // actually acts like a spy thanks to the below setting
            .defaultAnswer(CALLS_REAL_METHODS));
    
    credentialsService.process();
}

(read more in the Mockito documentation)


Spy on an object

@Test
void spyOnObject() {
    var encryptionService = mock(EncryptionService.class);
    var credentialsService = spy(new CredentialsService(encryptionService));

    credentialsService.process();
}

I'm usually using the first or last approach from the ones above (but the first one with dependencies injected by constructor - it works as well).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文