java - 如何对同步方法进行单元测试?

标签 java unit-testing testing synchronized

假设我有这样一个方法:

synchronized void incrementIndex() {
      index++;
}

如果多个线程同时尝试增加索引,我想对该方法进行单元测试以查看索引的最终值是否设置正确。假设我不知道方法声明中的“synchronized”关键字(而且我只知道方法的契约),我该如何进行测试?

附注如果有帮助,我正在使用 Mockito 编写测试用例。

最佳答案

您可以通过让多个线程执行该方法然后断言结果符合您的预期来对此进行测试。我怀疑这会有多有效和可靠。众所周知,多线程代码难以测试,这主要归结为仔细的设计。我肯定会建议添加测试,断言您期望通过 synchronized 实现的方法实际上具有 synchronized 修饰符。请参阅以下两种方法的示例:

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.junit.Test;

public class SyncTest {
  private final static int NUM_THREADS = 10;
  private final static int NUM_ITERATIONS = 1000;

  @Test
  public void testSynchronized() throws InterruptedException {
    // This test will likely perform differently on different platforms.
    ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);
    final Counter sync = new Counter();
    final Counter notSync = new Counter();

    for (int i = 0; i < NUM_THREADS; i++) {
      executor.submit(new Runnable() {
        @Override
        public void run() {
          for (int i = 0; i < NUM_ITERATIONS; i++) {
            sync.incSync();
            notSync.inc();
          }
        }
      });
    }

    executor.shutdown();
    executor.awaitTermination(5, TimeUnit.SECONDS);
    assertThat(sync.getValue(), is(NUM_THREADS * NUM_ITERATIONS));
    assertThat(notSync.getValue(), is(not(NUM_THREADS * NUM_ITERATIONS)));
  }

  @Test
  public void methodIncSyncHasSynchronizedModifier() throws Exception {
    Method m = Counter.class.getMethod("incSync");
    assertThat(Modifier.isSynchronized(m.getModifiers()), is(true)); 
  }

  private static class Counter {
    private int value = 0;

    public synchronized void incSync() {
      value++;
    }

    public void inc() {
      value++;
    }

    public int getValue() {
      return value;
    }
  }
}

关于java - 如何对同步方法进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26967036/

相关文章:

testing - 在运行时为 NUnit 测试提供参数

scala - 如何测试正确模板的渲染

java - IntelliJ 中的 Spring Web Flow 支持

unit-testing - Visual Studio 环境中 Jasmine 中的 Typescript 测试

java - 如何避免将空值插入主键或非空列?

unit-testing - Angular2 - 单元测试表单提交

模拟 java.nio.ByteBuffer 类时出现 java.lang.UnsupportedOperationException

java - BeanCreationException : Error creating bean with name 'flywayInitializer'

java - 是否可以检查哪些 gradle 依赖项包含给定的类?

java - 如何为 Java 源文件中的多个问题编写 Eclipse QuickFix