从匿名类

时间:2018-02-13 10:54:22

标签: java unit-testing callback mocking anonymous-class

我是单位测试的新手,我不知道如何解决这个问题,所以我很感激您的意见。

相关代码:

public class Repository {

@Override
public void getUnifiedFoo(@NonNull final Foo foo1,
        @NonNull final GetUnifiedFooCallback getUnifiedFooCallback) {

    fooDataSource.getFoo2(foo1,new GetFoo2Callback() {

                @Override
                public void onGetFooSuccess(Foo foo2) {
                    UnifiedFoo unifiedFoo= createUnifiedFoo(foo1, foo2);
                    getUnifiedFooCallback.onGetSuccess(unifiedFoo);
                }

                @Override
                public void onGetMedicationCallbackFailure(Throwable t) {
                    getUnifiedFooCallback.onGetFailure(t);
                }
            });
      }
}

private createUnifiedFoo(Foo foo1, Foo foo2){

   return new UnifiedFoo(
              foo1.getMember1,
              foo1.getMember2,
              foo2.getMember3,
              foo2.getMember4,
      );
}

我的问题是:

  1. Shoud' createUnifiedFoo(Foo foo1,Foo foo2)'包装是否私密并单独测试?
  2. 在这种情况下,如果可以,那么在测试中是否有任何一点需要调用1个方法(在本例中为fooDataSource.getFoo(...))?
  3. 如果它可以接受测试' createUnifiedFoo ...'当在匿名类中回调时,我如何捕获回调,以便在' onGetFooSuccess(Foo foo2)'被调用,我接受foo1存根,foo2存根并断言它们的字段以确认它们包含正确的值?
  4. 谢谢。

1 个答案:

答案 0 :(得分:0)

实际上这是一个意见问题。

就个人而言,我会将createUnifiedFoo移到另一个班级

class FooUnifier {
    public UnifiedFoo of(Foo1 f1, Foo2 f2) {...
}

所以在存储库中你有

class Repository {
    FooUnifier unifier = new FooUnifier(); // or @Autowired

        ...
        getUnifiedFooCallback.onGetSuccess(unifier.of(foo1, foo2));
}

并在单元测试中

@RunWith(MockitoJUnitRunner.class)
class Test {
    @InjectMocks
    Repository sut;

    @Mock
    FooDatasource datasource;
    @Mock
    FooUnifier unifier;
    @Mock
    UnifiedFoo unifiedFoo;
    @Mock
    GetUnifiedFooCallback callback;

    @Before
    public void mockUnifiedFoo()
        when(unifier.of(any(), any())).thenReturn(unifiedFoo);
    }
}

这将创建模拟并将它们设置为Repository的成员,允许您创建这样的测试用例

@Test
public void unificationSuccess() {
    Foo1 foo1 = mock(Foo1.class);
    Foo2 foo2 = mock(Foo2.class);
    when(datasource.getFoo2(foo1, eq(callback)))
       .then(i -> {
           callback.onGetSuccess(unifiedFoo);
       });
    sut.getUnifiedFoo(foo1, callback);

    // make sure the unified foo was created
    verify(unifier).of(foo1, foo2);
    // make sure the callback was called
    verify(callback).onGetSuccess(unifiedFoo);
}

所以基本上你设置你的测试用例,然后用正确的参数验证所有正确的调用。

您可以单独测试FooUnifier的正确行为。