我在测试具有ref参数的方法时遇到问题。我不是库/代码所有者,所以我无法更改它,所以请不要建议我删除ref参数。
我正在使用本网站作为参考: http://ayende.com/wiki/Rhino%20Mocks%203.5.ashx#OutandRefarguments
以下是测试:
[Test]
public void TestBuildSimpleProfile()
{
// arrange
var barMock = MockRepository.GenerateStrictMock<ICommandBar>();
var controlBuilder = new ControlBuilder(barMock);
var user = new Usuario();
user.PRF_PERFIS = new Perfis();
var perfil = new Perfil();
perfil.FNC_FUNCIONALIDADES = new Funcionalidades();
var func1 = new Funcionalidade();
func1.FNC_NU_ID = 1;
func1.FNC_FL_ATIVO = true;
func1.FNC_NO_CHAVE = "Associar Registros";
func1.FNC_DE_FUNCIONALIDADE = "{0653aeac-c5ef-46fa-9e99-408719296ed3}";
perfil.FNC_FUNCIONALIDADES.Add(func1);
user.PRF_PERFIS.Add(perfil);
var funcs = new List<IFunctionality>();
funcs.Add(new FunctionalityAttribute(1,"Associar Registros", "{0653aeac-c5ef-46fa-9e99-408719296ed3}", "SGIGT", true,"admin,editor"));
var uid = new UIDClass() { Value = "{0653aeac-c5ef-46fa-9e99-408719296ed3}" };
var arg = Arg<object>.Ref(Is.Anything(), 0).Dummy;
// act
controlBuilder.Build(user, funcs);
// assert
barMock.AssertWasCalled(x => x.Add(uid, ref arg), y => y.IgnoreArguments());
}
以下是我发现的错误:
Rhino.Mocks.Exceptions.ExpectationViolationException:ICommandBar.Add(ESRI.ArcGIS.esriSystem.UIDClass,0);预期#0,实际#1。
我已经尝试了很多方法,但它根本行不通。构建方法实现如下。这只是接收要构建的函数列表和具有相关功能的用户。如果他有一个函数,那么应该使用add方法构建它。
public void Build(Usuario u, List<IFunctionality> funcsToBuild)
{
if (u == null)
throw new ArgumentNullException("u");
if (funcsToBuild == null)
throw new ArgumentNullException("funcsToBuild");
if (u.PRF_PERFIS == null || u.PRF_PERFIS.Count <= 0)
return;
var functionList = (from funcs in funcsToBuild
select funcs.FunctionDescription).ToList();
var userFuncs = (from profile in u.PRF_PERFIS
from functionality in profile.FNC_FUNCIONALIDADES
where functionality.FNC_FL_ATIVO.HasValue && functionality.FNC_FL_ATIVO.Value && functionList.Contains(functionality.FNC_DE_FUNCIONALIDADE)
select new FunctionalityAttribute((int)functionality.FNC_NU_ID.Value,functionality.FNC_NO_CHAVE, functionality.FNC_DE_FUNCIONALIDADE, "SGIGT", true, "")).Cast<IFunctionality>().OrderBy(x => x.FunctionId).ToList();
for (int index = 0; index < userFuncs.Count; index++)
{
IFunctionality t = userFuncs[index];
object i = index;
var functionality = t;
var uid = new UIDClass() {Value = functionality.FunctionDescription};
var ci = _commandBar.Add(uid, ref i);
}
}
有人可以帮助我吗?
答案 0 :(得分:8)
您可以使用Arg&lt;&gt;匹配对Out / Ref参数的期望。如果您不关心实际值,可以使用以下内容:
barMock.AssertWasCalled(x =>
x.Add(Arg<UIDClass>.IsAnything(),
ref Arg<object>.Ref(Is.Anything(), null).Dummy);
如果你关心匹配输入/输出值,那么你可以改用:
barMock.AssertWasCalled(x =>
x.Add(Arg<UIDClass>.Is.Equal(uid),
ref Arg<object>.Ref(Is.Same(input), output).Dummy);
我认为您的测试很可能失败,因为uid与传入ICommandBar的实例不同,而不是Ref参数的特定问题。您可以使用如上所示的Equals解决此问题,而不是使用引用相等。
如果所有其他方法都失败并且UIDClass没有正确实现equals,则可以始终使用匹配的谓词:
barMock.AssertWasCalled(x =>
x.Add(Arg<UIDClass>.Is.Matching(
delegate(UIDClass u) { return u.Value == uid.Value; }
),
ref Arg<object>.Ref(Is.Same(input), output).Dummy);
答案 1 :(得分:1)
[Fact]
public void Test_Ref()
{
var barMock = MockRepository.GenerateMock<IDoSomething>();
Composer composer = new Composer(barMock);
int number = 12;
composer.addStuff(0, number);
barMock.AssertWasCalled(x => x.Add(0, ref number),
y=>y.IgnoreArguments().Repeat.Times(1));
}
public class Composer
{
private IDoSomething dosomething;
public Composer(IDoSomething doSomething)
{
this.dosomething = dosomething;
}
public void addStuff(int id, int value)
{
dosomething.Add(id, ref value);
}
}
public interface IDoSomething
{
void Add(int id, ref int value);
}
我认为这个问题可能与MockRepository.GenerateStrictMock()和MockRepository.GenerateMock()有关;然后在IMethodoptions上添加Repeat.Times(1)。您应该能够确保根据具有此代码的func列表中的项目数来调用Add。