仪表式计数器测试案件失败

发布于 2025-01-31 16:29:52 字数 692 浏览 5 评论 0 原文

我已经通过注入 meterRegistry 并增加了计数,在我的服务中实现了千分尺Prometheus计数器,但我也写了一个测试用例,但是当我运行测试用例时,我会得到:

“ java.lang.nullpointerexception:无法调用 “ io.micrometer.core.instrument.MeterRegistry.Counter(String, string [])“因为“ this.meterregistry”为null”。

服务文件:

@Autowired
private MeterRegistry meterRegistry;
    
public void counterIncrement() { 
    meterRegistry.counter("test_count").increment();
}

测试案例文件:

@MockBean
private MeterRegistry registry;
     
@Test
void testCounter() {
    //  invoking counterIncrement();
}

I have implemented Micrometer Prometheus counter in my service by injecting MeterRegistry and incrementing the count as shown below, and I have written a test case as well, but when I am running the test case, I am getting:

"java.lang.NullPointerException: Cannot invoke
"io.micrometer.core.instrument.MeterRegistry.counter(String,
String[])" because "this.meterRegistry" is null".

Service file:

@Autowired
private MeterRegistry meterRegistry;
    
public void counterIncrement() { 
    meterRegistry.counter("test_count").increment();
}

Test case file:

@MockBean
private MeterRegistry registry;
     
@Test
void testCounter() {
    //  invoking counterIncrement();
}

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

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

发布评论

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

评论(4

紫瑟鸿黎 2025-02-07 16:29:52

您可以使用 SimpleSemeterRegistry

  @Test
  void testCounter() {
    var meterRegistry = new SimpleMeterRegistry();
    Metrics.addRegistry(meterRegistry);

    //  invoke counterIncrement();

    var actual = meterRegistry.counter("test_count").count();
    
    assertEquals(1.0d, actual);
  }

You can test metrics without Mockito using SimpleMeterRegistry

  @Test
  void testCounter() {
    var meterRegistry = new SimpleMeterRegistry();
    Metrics.addRegistry(meterRegistry);

    //  invoke counterIncrement();

    var actual = meterRegistry.counter("test_count").count();
    
    assertEquals(1.0d, actual);
  }
倚栏听风 2025-02-07 16:29:52

您如何创建正在测试的课程?
由于注册表永远不会实例化,因此您如何设置测试的方式似乎有所了解。

检查您是否以正确的方式使用 @mockbean 。这将在应用程序上下文中替换BEAN,如果您在测试中不旋转弹簧上下文,则它将行不通。请参阅此帖子以获取更多信息。

另一种方法是使用 @mock 并将注册表注入构造函数,例如:

@ExtendWith(MockitoExtension.class)
public class MyServiceTest {

  @Mock
  private MeterRegistry registry;

  private MyService myService;

  @BeforeEach
  void setup() {
    myService = new MyService(registry);
  }

  @Test
  void testCounter() {
    var counter = mock(Counter.class);
    given(registry.counter(any(String.class))).willReturn(counter);
    myService.counterIncrement();
  }

How do you create your class under test?
Since the registry is never instantiated, something seems up with how you setup your test.

Check that you are using the @MockBean in the correct way. This will replace the bean in the application context and if you do not spin up a spring context in your test, it will not work. See this post for more info.

A different approach would be to use @Mock and inject the registry in the constructor, example:

@ExtendWith(MockitoExtension.class)
public class MyServiceTest {

  @Mock
  private MeterRegistry registry;

  private MyService myService;

  @BeforeEach
  void setup() {
    myService = new MyService(registry);
  }

  @Test
  void testCounter() {
    var counter = mock(Counter.class);
    given(registry.counter(any(String.class))).willReturn(counter);
    myService.counterIncrement();
  }
绮烟 2025-02-07 16:29:52

根据您使用的Junit版本,您需要将注释添加到测试类中。 junit 5: @extendwith(mockitoextension.class)或for junit 4: @runwith(MockitoJunitRunner.Class)

Depending on which junit version you are using you need to add the annotation to your test class. Junit 5: @ExtendWith(MockitoExtension.class) or for Junit 4: @RunWith(MockitoJUnitRunner.class)

傲世九天 2025-02-07 16:29:52

根据测试和服务的不同,有几种处理缺失的计量记录的方法。

  1. 如果您在测试中使用弹簧上下文,请尝试使用测试配置创建MeterRegistry bean。
  2. 如果您的测试使用一些模拟框架,则可以用
  3. 如果您只是简单地将成员计算机为非私有化。您可以在某些设置方法中将其设置为SimpleMeterRegistry,并用 @BeForeEach 播种,如@Checketts 在评论中
  4. 如果嘲笑仪表注册表变得复杂,您可以轻松地构建和使用一些提供注册表并模拟该工厂的工厂。一个非常简单的工厂可以做,例如带有自动计量记录的Spring @component ,以及工厂的一些公共Getter。
  5. 您可以使用工厂方法模式如Wikipedia中所述在您的服务子类中,并在测试中使用此子类。 (请注意,四人的帮派确实使用了 >,您需要一种非静态方法。)

我偏爱解决方案3,但会在适当时使用解决方案1。我添加了解决方案4和5仅仅是因为可能还有一些其他原因和特殊情况使这些解决方案成为一个不错的选择。如果是这样,我更喜欢4比5。

Depending on the test and the service there are several ways to deal with the missing MeterRegistry.

  1. If you use a spring context in your test, try to use a test configuration to create the MeterRegistry bean.
  2. If your test uses some Mock framework, you could mock the MeterRegistry as suggested by by @Hans-Christian.
  3. If you simply make the member meterRegistry non-private. You could set it to a SimpleMeterRegistry in some setup method, anotated with @BeforeEach as suggested by @checketts in the comments.
  4. If mocking the meter registry gets complicated, you could easily build and use some factory that provides the registry and mock this factory. A very easy factory will do, e.g. a spring @Component with an autowired MeterRegistry and some public getter for the factory.
  5. You could use the factory method pattern as described in wikipedia to get the MeterRegistry, overwrite the factory method in a subclass of your service and use this subclass in the test. (Note that the gang of four did use a static factory method, you'll need a non-static method.)

I favour solution 3 but would use solution 1 whenever appropriate. I've added solutions 4 and 5 just because there might be some additional reasons and special cases that make these solutions a good choice. If so, I prefer 4 over 5.

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