JAVA Unit Test Mock framework

EasyMock


TestClassA {

 void setup() {
  //Create mock
  ClassBeingMocked mock1 = EasyMock.createMock(ClassBeingMocked);
 }


 void testMethod() {
  //Setup expectations
  EasyMock.expect(mock1.getAge()).andReturn(10);
  //Replay mode
  EasyMock.replay(mock1);
  //Test
  ClassBeingTested source = new ClassBeingTested();
  source.calculateAge(mock1);
  //Assertions
  assertEquals(50, source.getAverageAge());
  //Verification mode
  EasyMock.verify(mock1);
 }
}

Mockito


TestClassA {


 void setup() {
  //Create mock
  ClassBeingMocked mock1 = Mockito.Mock(ClassBeingMocked);
 }


 void testMethod() {
  //Setup expectations
  Mockito.when(mock1.getAge()).thenReturn(10);

  //Test
  ClassBeingTested source = new ClassBeingTested();
  source.calculateAge(mock1);

  //Assertions
  assertEquals(50, source.getAverageAge());

  //Verification mode
  Mockito.verify(source).someInternalMethodCalled();
 }
}

InjectMocks, Mock usage

ReflectionTestUtils to set private value.

    @InjectMocks
    private ComponentA componentA;

    @Mock
    private ComponentB componentB;

    @Before
    public void setUp()
    {
        Mockito.when(componentB.B(Mockito.anyObject())).thenReturn(null);

        ReflectionTestUtils.setField(componentA, "Feature", true);
    }

JMockit


@Mocked  //用@Mocked标注的对象,不需要赋值,jmockit自动mock
MyObject obj;
 
@Test
public void testHello() {
    new NonStrictExpectations() {//录制预期模拟行为
        {
            obj.hello("Zhangsan");
            returns("Hello Zhangsan");
            //也可以使用:result = "Hello Zhangsan";
        }
    };
    assertEquals("Hello Zhangsan", obj.hello("Zhangsan"));//调用测试方法
    new Verifications() {//验证预期Mock行为被调用
        {
            obj.hello("Hello Zhangsan");
            times = 1;
        }
    };
}

PowerMock


@RunWith(PowerMockRunner.class)
@PrepareForTest({
 StaticService.class
})
public class ItemServiceTest {

 @Mock
 private ItemRepository itemRepository;

 @InjectMocks
 private ItemService itemService;

 @Before
 public void setUp() throws Exception {
  MockitoAnnotations.initMocks(this);
 }

 @Test
 public void readItemDescriptionWithoutIOException() throws IOException {

  //
  // Given
  //
  String fileName = "DummyName";

  mockStatic(StaticService.class);
  when(StaticService.readFile(fileName)).thenReturn("Dummy");

  //
  // When
  //
  String value = itemService.readItemDescription(fileName);

  //
  // Then
  //
  verifyStatic(times(1));
  StaticService.readFile(fileName);
  assertThat(value, equalTo("Dummy"));
 }
}

JUnit vs TestNG


JUnit 4 和 TestNG 在表面上是相似的。然而,设计 JUnit 的目的是为了分析代码单元,而 TestNG 的预期用途则针对高级测试。对于大型测试套件,我们不希望在某一项测试失败时就得重新运行数千项测试,TestNG 的灵活性在这里尤为有用。

 

 

C#单元测试中的模拟(mock)是一种常用的技术,用于在测试中创建虚拟的对象,以替代真实的依赖项,以确保测试的可预测性和可重复性。 在C#中,常用的单元测试模拟框架包括Moq、NSubstitute和FakeItEasy等。这些框架提供了一些API,使得我们可以轻松地创建和配置模拟对象。 下面是一个使用Moq进行模拟的示例: ```csharp // 需要进行单元测试的类 public class Calculator { private IDataProvider _dataProvider; public Calculator(IDataProvider dataProvider) { _dataProvider = dataProvider; } public int AddNumbers(int a, int b) { // 从数据提供者获取数据 int data = _dataProvider.GetData(); // 执行计算 int result = a + b + data; return result; } } // 数据提供者的接口 public interface IDataProvider { int GetData(); } // 使用Moq创建并配置模拟对象进行测试 [Test] public void AddNumbers_ShouldReturnCorrectSum() { // 创建模拟对象 var dataProviderMock = new Mock<IDataProvider>(); // 配置模拟对象的行为 dataProviderMock.Setup(dp => dp.GetData()).Returns(10); // 创建被测试对象,并传入模拟对象 var calculator = new Calculator(dataProviderMock.Object); // 执行测试 int result = calculator.AddNumbers(1, 2); // 验证结果 Assert.AreEqual(13, result); } ``` 在上面的示例中,我们使用Moq创建了一个IDataProvider的模拟对象,并配置了模拟对象的行为。然后,我们创建了被测试对象Calculator,并将模拟对象传递给它的构造函数。最后,我们执行了AddNumbers方法,并验证了最终的结果。 使用模拟对象可以帮助我们解决以下问题: 1. 解除对外部依赖项(如数据库、网络请求等)的依赖,使得测试更加独立和可控。 2. 模拟复杂的对象和行为,以测试各种边界情况和异常情况。 3. 提供自定义的返回值或异常,以测试不同的路径和条件。 相关问题: 1. 除了Moq之外,还有哪些常用的C#单元测试模拟框架? 2. 在使用模拟对象时,如何验证方法的参数是否被正确调用? 3. 如何配置模拟对象的返回值或抛出异常? 4. 在一些特殊情况下,如何模拟异步方法的行为? 5. 在多个测试中共享模拟对象有什么注意事项?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值