Moq是.NET平台下的单元测试框架。Moq的作用是解除要测试的对象对其所依赖的对象的依赖。(这句话比较绕,自习体会一下!)在稍微复杂一点的系统,一个被测试的对象通常会依赖多个对象。为了测试某个对象,该对象必须依赖于抽象,而不是具体。比如A依赖于B,B是A的一个引用,在A的某个方法里面来实例化,然后调用B的某些方法,这样的依赖耦合性太高,一旦B创建失败,那么A也将创建失败。为了避免这种问题,需要依赖于抽象,具体来说就是使用依赖注入,通过控制反转的方式来解决这个问题。
对于被测试的对象,其所依赖的对象,我们采用依赖注入方式来解除耦合,那么这个能够Mock的对象中如果还依赖于其他非依赖注入的对象,我们使用Mock会不会失败呢?根据Mock的定义,Mock执行的动作并不会真的执行,那么从原理上来说,Mock的对象中依赖于其他非依赖注入的对象的动作我们可以不用去关注。
IRandomHelperAdapter.cs
namespace CommonTools
{
public interface IRandomHelperAdapter
{
int GetRandom();
}
}
RandomHelper.cs
namespace CommonTools
{
internal class RandomHelper
{
public static int GetRandom(int seed)
{
return new Random(seed).Next();
}
}
}
RandomHelperAdapter.cs
namespace CommonTools
{
class RandomHelperAdapter : IRandomHelperAdapter
{
public int GetRandom()
{
int seed = RandomSeed.GetRandom();
return RandomHelper.GetRandom(seed);
}
}
}
RandomProvider.cs
namespace CommonTools
{
public class RandomProvider
{
private readonly IRandomHelperAdapter randomHelperAdapter;
public RandomProvider()
:this(new RandomHelperAdapter())
{
}
public RandomProvider(IRandomHelperAdapter randomHelperAdapter)
{
this.randomHelperAdapter = randomHelperAdapter;
}
public int GetRandomNumber()
{
return randomHelperAdapter.GetRandom();
}
}
}
RandomSeed.cs
namespace CommonTools
{
internal class RandomSeed
{
public static int GetRandom()
{
return 10;
}
}
}
RandomProviderTest.cs
using System.Diagnostics;
using CommonTools;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using Moq;
namespace RandomTestProject
{
/// <summary>
///这是 RandomProviderTest 的测试类,旨在
///包含所有 RandomProviderTest 单元测试
///</summary>
[TestClass]
public class RandomProviderTest
{
private Mock<IRandomHelperAdapter> randomHelperAdapterMock;
private RandomProvider randomProvider;
private int result;
[TestInitialize]
public void Initialize()
{
randomHelperAdapterMock = new Mock<IRandomHelperAdapter>(MockBehavior.Strict);
randomProvider = new RandomProvider(randomHelperAdapterMock.Object);
result = 0;
}
[TestCleanup]
public void CleanUp()
{
}
/// <summary>
///GetRandomNumber 的测试
///</summary>
[TestMethod]
public void GetRandomNumberTest()
{
randomHelperAdapterMock.Setup(x => x.GetRandom()).Returns(result);
randomProvider.GetRandomNumber();
}
}
}
结果: