Skip to content

Commit 915b895

Browse files
committed
Develop a working version of ItByRef class. The idea was correct but the setup can be flawed if not executed in correct sequence. Wrote tests to assert the behaviors on how Setup works only specific values passed by ref.
1 parent 8dd4663 commit 915b895

File tree

4 files changed

+105
-84
lines changed

4 files changed

+105
-84
lines changed
Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.Collections.Generic;
3+
using Moq;
24

35
namespace Rubberduck.ComClientLibrary.UnitTesting.Mocks
46
{
@@ -7,16 +9,24 @@ public class ItByRef<T>
79
// Only a field of a class can be passed by-ref.
810
public T Value;
911

10-
public static ItByRef<T> Is(T input, Func<T, bool> condition)
12+
public delegate void ByRefCallback(ref T input);
13+
14+
public ByRefCallback Callback { get; }
15+
16+
public static ItByRef<T> Is(T initialValue)
17+
{
18+
return Is(initialValue, null);
19+
}
20+
21+
public static ItByRef<T> Is(T initialValue, ByRefCallback action)
1122
{
12-
return condition(input)
13-
? new ItByRef<T>(input)
14-
: new ItByRef<T>(default);
23+
return new ItByRef<T>(initialValue, action);
1524
}
1625

17-
private ItByRef(T input)
26+
private ItByRef(T initialValue, ByRefCallback callback)
1827
{
19-
Value = input;
28+
Value = initialValue;
29+
Callback = callback;
2030
}
2131
}
2232
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Moq;
4+
using NUnit.Framework;
5+
using Rubberduck.ComClientLibrary.UnitTesting.Mocks;
6+
7+
namespace RubberduckTests.ComMock
8+
{
9+
[TestFixture]
10+
[Category("ComMock.ItByRef")]
11+
public class ItByRefTests
12+
{
13+
[Test]
14+
public void Basic_Ref_Setup()
15+
{
16+
var mock = new Mock<ITestRef>();
17+
var byRef = ItByRef<int>.Is(1, (ref int x) => x = 2);
18+
mock.Setup(x => x.DoInt(ref byRef.Value)).Callback(byRef.Callback);
19+
var obj = mock.Object;
20+
obj.DoInt(ref byRef.Value);
21+
22+
Assert.AreEqual(2, byRef.Value);
23+
mock.Verify(x => x.DoInt(ref byRef.Value), Times.Once);
24+
}
25+
26+
[Test]
27+
public void Multiple_Ref_Setup()
28+
{
29+
var mock = new Mock<ITestRef>();
30+
var byRef1 = ItByRef<int>.Is(1, (ref int x) => x = 2);
31+
var byRef2 = ItByRef<int>.Is(3, (ref int x) => x = 5);
32+
mock.Setup(x => x.DoInt(ref byRef1.Value)).Callback(byRef1.Callback);
33+
mock.Setup(x => x.DoInt(ref byRef2.Value)).Callback(byRef2.Callback);
34+
35+
var obj = mock.Object;
36+
obj.DoInt(ref byRef1.Value);
37+
obj.DoInt(ref byRef2.Value);
38+
39+
Assert.AreEqual(2, byRef1.Value);
40+
Assert.AreEqual(5, byRef2.Value);
41+
mock.Verify(x => x.DoInt(ref byRef1.Value), Times.Once);
42+
mock.Verify(x => x.DoInt(ref byRef2.Value), Times.Once);
43+
}
44+
45+
[Test]
46+
public void Null_Ref_Setup()
47+
{
48+
var mock = new Mock<ITestRef>();
49+
var byRef = ItByRef<string>.Is(null, (ref string x) => x = string.Empty);
50+
mock.Setup(x => x.DoString(ref byRef.Value)).Callback(byRef.Callback);
51+
var obj = mock.Object;
52+
obj.DoString(ref byRef.Value);
53+
54+
var testString = "abc";
55+
obj.DoString(ref testString);
56+
57+
Assert.AreEqual(string.Empty, byRef.Value);
58+
Assert.AreEqual("abc", testString);
59+
60+
mock.Verify(x => x.DoString(ref byRef.Value), Times.Once);
61+
}
62+
63+
[Test]
64+
public void Basic_Ref_Setup_Returns()
65+
{
66+
var mock = new Mock<ITestRef>();
67+
var byRef = ItByRef<int>.Is(1);
68+
mock.Setup(x => x.ReturnInt(ref byRef.Value)).Returns(2);
69+
var obj = mock.Object;
70+
var actual = obj.ReturnInt(ref byRef.Value);
71+
72+
var negativeRef = 0;
73+
var negativeActual = obj.ReturnInt(ref negativeRef);
74+
75+
Assert.AreEqual(2, actual);
76+
Assert.AreEqual(0, negativeActual);
77+
}
78+
79+
}
80+
}

RubberduckTests/ComMock/MockProviderTests.cs

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Runtime.InteropServices;
43
using Moq;
54
using NUnit.Framework;
@@ -538,83 +537,6 @@ public void Mock_Setup_Property_Specified_Args_Returns_Specified_Value(string II
538537
}
539538
}
540539

541-
[Test]
542-
[TestCase("abc", "abc", true)]
543-
[TestCase("abc", "def", false)]
544-
[TestCase("abc", "", false)]
545-
[TestCase("", "abc", false)]
546-
[TestCase("", "", true)]
547-
[TestCase("", null, false)]
548-
[TestCase(1, 1, true)]
549-
[TestCase(1, 2, false)]
550-
[TestCase(1, null, false)]
551-
552-
// For null as expected, any values will be true
553-
[TestCase(null, "", true)]
554-
[TestCase(null, 1, true)]
555-
public void Test_ItByRef_Value_Is<T>(T expected, T input, bool areEqual)
556-
{
557-
Test_ItByRef_Is(expected, input, areEqual);
558-
}
559-
560-
[Test]
561-
public void Test_ItByRef_Object_Is_NotSame()
562-
{
563-
var obj1 = new Mock<object>();
564-
obj1.As<ITest1>();
565-
var obj2 = new Mock<object>();
566-
obj2.As<ITest1>();
567-
568-
Test_ItByRef_Is(obj1.Object, obj2.Object, false);
569-
}
570-
571-
[Test]
572-
public void Test_ItByRef_Object_Is_DifferentFace_Same()
573-
{
574-
var obj1 = new Mock<ITest1>();
575-
var obj2 = obj1.As<ITest2>();
576-
577-
Test_ItByRef_Is((object)obj1.Object, (object)obj2.Object, true);
578-
}
579-
580-
[Test]
581-
public void Test_ItByRef_Object_Is_Null_NotSame()
582-
{
583-
var obj1 = new Mock<object>();
584-
obj1.As<ITest1>();
585-
586-
Test_ItByRef_Is(obj1.Object, null, false);
587-
}
588-
589-
[Test]
590-
public void Test_ItByRef_Object_Is_Same()
591-
{
592-
var obj1 = new Mock<object>();
593-
obj1.As<ITest1>();
594-
595-
Test_ItByRef_Is(obj1.Object, obj1.Object, true);
596-
}
597-
598-
public void Test_ItByRef_Is<T>(T expected, T input, bool areEqual)
599-
{
600-
var actual = TestRef(ref ItByRef<T>.Is(input, x => EqualityComparer<T>.Default.Equals(x, expected)).Value);
601-
602-
var test = expected == null ? null : string.Concat("ref ", expected.ToString());
603-
if (areEqual)
604-
{
605-
Assert.AreEqual(test, actual);
606-
}
607-
else
608-
{
609-
Assert.AreNotEqual(test, actual);
610-
}
611-
}
612-
613-
private static string TestRef<T>(ref T refValue)
614-
{
615-
return refValue == null ? null : string.Concat("ref ", refValue.ToString());
616-
}
617-
618540
/* Commented to remove the PIA reference to Scripting library, but keeping code in one day they fix type equivalence?
619541
[Test]
620542
public void Type_From_ITypeInfo_Are_Equivalent()

RubberduckTests/ComMock/TypesForTesting.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ public interface ITest3
2121
void DoObject(object something);
2222
}
2323

24+
public interface ITestRef
25+
{
26+
void DoInt(ref int something);
27+
void DoString(ref string something);
28+
void DoObject(ref object something);
29+
30+
int ReturnInt(ref int something);
31+
}
32+
2433
public class ConvertibleTest : IConvertible
2534
{
2635
private readonly TypeCode _code;

0 commit comments

Comments
 (0)