问题描述
我们有一个 Xamarin Android 应用程序,我正在尝试添加更好的单元测试。我们将 SimpleInjector 用于我们的 DI 和 NUnit/Moq 用于我们的测试运行和模拟框架。过去,我使用 Mockito/Robolectric 和 Dagger for DI 使用原生 Android 应用程序完成了非常类似的工作,一旦正确配置,一切都非常无缝。
我正在尝试与之前的项目进行类似级别的测试,事实证明这是非常具有挑战性的。 C# 和 Xamarin 的模拟框架似乎依赖于有接口或抽象类来模拟而不是具体的实现,并且当这些类没有无参数构造函数时,它们会出现进一步的问题。 Mockito 没有同样的限制,并且中间没有 JNI 来干扰模拟库必须执行的类反射来构建对象。 由于上述原因,您似乎无法模拟具体的 Android 类,如果可以,则文档大多不存在。 有没有人解决过这个问题或知道我不知道的技巧?
例如:
我们正在扩展 Android 类 Android.OS.CountDownTimer 并通过构造函数注入一个工厂,该工厂使用构造函数参数(long millisInFuture、long countDownInterval)为我们创建一个新的计时器对象。实现起来很简单。 我想测试在我们的 OnStart() 片段方法中调用 Factory.Create() 方法和 Timer.Start() 方法。
在测试类中,
var countDownTimerFactory = new Mock<ITimerFactory>(); //This returns our concrete class through DI
var mockTimer = new Mock<CountDownTimer>(MockBehavior.Default,new object[] { _WAIT_TIME_MS,_COUNTDOWN_INTERVAL_MS });
// Those values are 2000 and 1000.
// If you try building this mock without the constructor args you get the parameterless constructor error
countDownTimerFactory.Setup(factory => factory.Create(It.IsAny<long>(),It.IsAny<long>())).Returns(mockTimer.Object);
OurFragment subject = new OurFragment(countDownTimerFactory.Object);
countDownTimerFactory.Verify(x => x.Create(_WAIT_TIME_MS,_COUNTDOWN_INTERVAL_MS));
mockTimer.Verify(x => x.Start());
这段代码会炸掉,因为在dexpath上找不到代理类。 stacktrace
验证我们的计时器类构造函数确实在测试期间被调用并在基调用中的某处爆炸。
public OurTimer (long millisInFuture,long countDownInterval) : base(millisInFuture,countDownInterval)
{
}
这仅适用于 CountDownTimer 类,但几乎可以选择任何 Android 类,您都会遇到相同的问题。我是否只是遗漏了一些我应该理解的 Xamarin Android 开发核心内容并且没有相关文档,或者这是一个未解决的问题,人们只是不在 Xamarin 中进行此级别的单元测试?
谢谢!
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)