使用 C# .NetFrameWork 4.7, Moq 1.4
我正在测试一种进行 2 个接口调用的方法。接口方法接受 1 个参数,该参数也是一个接口。很难对此进行测试,Moq 会抛出铸造错误。
具有以下特征的 2 个连续调用:
InterfaceUnderTest.MethodUnderTest(IEnumerable<IParamInterface>)
完整的代码示例可以在 github 上找到:https : //github.com/JayZhang727/UnitTestingInterfaceParams
以下是基本结构:
导入的接口和实现我无法更改:
public interface IWorkInterface
{
string DoWork(IEnumerable<IParamInterface> para);
}
public interface IParamInterface
{
IParamDataInterface GetParamData();
}
public interface IParamDataInterface
{
string Id { get; set; }
}
public class ParamClass<T> : IParamInterface where T : IParamDataInterface
{
public T ParamData { get; set; }
public ParamClass()
{
}
public ParamClass(T para)
{
this.ParamData = para;
}
public IParamDataInterface GetParamData()
{
return ParamData;
}
}
public class ParamClassA : IParamDataInterface
{
public ParamClassA()
{
this.Id = "Id";
this.ParamClassAVar = 123;
}
public string Id { get; set; }
public int ParamClassAVar { get; set; }
}
public class ParamClassB : IParamDataInterface
{
public ParamClassB()
{
this.Id = "Id";
this.ParamClassBVar = "not 123";
}
public string Id { get; set; }
public string ParamClassBVar { get; set; }
}
这是被测类:
public ClassUnderTest(IWorkInterface workInt)
{
this.WorkClient = workInt;
}
public IWorkInterface WorkClient { get; set; }
public string MethodUnderTest()
{
var result = string.Empty;
//Class A is an implementation of IParamDataInterface
var a = new ParamClassA();
var theParamA = new ParamClass<ParamClassA>(a);
var listA = new List<IParamInterface>();
listA.Add(theParamA);
result = WorkClient.DoWork(listA);
//Class B is also an implementation of IParamDataInterface
var b = new ParamClassB();
var theParamB = new ParamClass<ParamClassB>(b);
var listB = new List<IParamInterface>();
listB.Add(theParamB);
result = result + WorkClient.DoWork(listB);
return result;
}
这是我尝试过的测试调用:
private Mock<IWorkInterface> mockClient;
[TestMethod()]
public void DoWorkTest()
{
mockClient = new Mock<IWorkInterface>(MockBehavior.Strict);
var target = new ClassUnderTest(mockClient.Object);
var mockSquence = new MockSequence();
mockClient.InSequence(mockSquence).Setup(ec => ec.DoWork(It.Is<List<IParamInterface>>(el => ((ParamClassA)((ParamClass<ParamClassA>)el[0]).GetParamData()).ParamClassAVar == 123))).Returns("123");
mockClient.InSequence(mockSquence).Setup(ec => ec.DoWork(It.Is<List<IParamInterface>>(el => ((ParamClassB)((ParamClass<ParamClassB>)el[0]).GetParamData()).ParamClassBVar == "not 123"))).Returns("not 123");
//act
target.MethodUnderTest();
//assert
mockClient.VerifyAll();
}
我收到关于无法从 A 类转换到 B 类的错误:
Message: Test method ClassUnderTesting.UnitTests.ClassUnderTestingTests.DoWorkTest threw exception:
System.InvalidCastException: Unable to cast object of type 'ClassUnderTesting.ParamClass`1[ClassUnderTesting.ParamClassA]' to type 'ClassUnderTesting.ParamClass`1[ClassUnderTesting.ParamClassB]'.
似乎最小起订量没有按顺序进行,出于某种原因,第二个设置胜过第一个设置,顺序似乎没有帮助。有谁知道我应该如何设置和测试这两个调用?
我会在没有顺序的情况下做到这一点。只需设置您的期望,以便在调用 DoWorkParamClassA
时返回“123”,并在调用ParamClassB
时返回“非 123”。
请注意,如果未给出第一个期望值,则它不会崩溃ParamClassA
:它根本不匹配(第二个和 也是如此ParamClassB
)。
mockClient
.Setup(ec => ec.DoWork(
It.Is<List<IParamInterface>>(el => el[0] is ParamClass<ParamClassA> && ((ParamClass<ParamClassA>)el[0]).ParamData.ParamClassAVar == 123)
))
.Returns("123");
mockClient
.Setup(ec => ec.DoWork(
It.Is<List<IParamInterface>>(el => el[0] is ParamClass<ParamClassB> && ((ParamClass<ParamClassB>)el[0]).ParamData.ParamClassBVar == "not 123")
))
.Returns("not 123");
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句