Skip to content

Commit 05f1d5f

Browse files
committed
Merge branch 'com-interop' into hotfix-release
2 parents 3b537f6 + 4d7d3c7 commit 05f1d5f

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ The format is loosely based on [Keep a Changelog](http://keepachangelog.com/en/1
1515
* Setup not triggered due to VB.NET transparently inserting superfluous type conversions into a setup expression (@InteXX, #1067)
1616
* Nested mocks created by `Mock.Of<T>()` no longer have their properties stubbed since version 4.14.0 (@vruss, @1071)
1717
* `Verify` fails for recursive setups not explicitly marked as `Verifiable` (@killergege, #1073)
18+
* `Mock.Of<>` fails for COM interop types that are annotated with a `[CompilerGenerated]` custom attribute (@killergege, #1072)
1819

1920

2021
## 4.14.6 (2020-09-30)

src/Moq/Linq/MockSetupsBuilder.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ private sealed class ReplaceMockObjectWithParameter : ExpressionVisitor
151151

152152
protected override Expression VisitMember(MemberExpression node)
153153
{
154-
if (node.Expression is ParameterExpression pe && pe.Type.IsDefined(typeof(CompilerGeneratedAttribute)))
154+
if (node.Expression is ParameterExpression pe && pe.Type.IsDefined(typeof(CompilerGeneratedAttribute)) && pe.Type.Name.Contains("f__AnonymousType"))
155155
{
156156
// In LINQ query expressions with more than one `from` clause such as:
157157
//

tests/Moq.Tests/ComCompatibilityFixture.cs

+48
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD, and Contributors.
22
// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt.
33

4+
using System.Runtime.CompilerServices;
5+
using System.Runtime.InteropServices;
6+
47
using Moq.Tests.ComTypes;
58

69
using Xunit;
@@ -100,5 +103,50 @@ public void COM_interop_type_indexer_setter_is_recognized_as_such()
100103
var setter = indexer.GetSetMethod(true);
101104
Assert.True(setter.IsSetAccessor() && setter.IsIndexerAccessor());
102105
}
106+
107+
[Fact]
108+
public void Can_create_mock_of_Excel_Workbook_using_Mock_Of_1()
109+
{
110+
_ = Mock.Of<GoodWorkbook>(workbook => workbook.FullName == "");
111+
}
112+
113+
[Fact]
114+
public void Can_create_mock_of_Excel_Workbook_using_Mock_Of_2()
115+
{
116+
_ = Mock.Of<BadWorkbook>(workbook => workbook.FullName == "");
117+
}
118+
119+
// The following two interfaces are simplified versions of the `_Workbook` interface from
120+
// two different versions of the `Microsoft.Office.Excel.Interop` interop assemblies.
121+
// Note how they differ only in one `[CompilerGenerated]` attribute.
122+
123+
[ComImport]
124+
[Guid("000208DA-0000-0000-C000-000000000046")]
125+
public interface GoodWorkbook
126+
{
127+
[DispId(289)]
128+
string FullName
129+
{
130+
[DispId(289)]
131+
[LCIDConversion(0)]
132+
[return: MarshalAs(UnmanagedType.BStr)]
133+
get;
134+
}
135+
}
136+
137+
[ComImport]
138+
[CompilerGenerated]
139+
[Guid("000208DA-0000-0000-C000-000000000046")]
140+
public interface BadWorkbook
141+
{
142+
[DispId(289)]
143+
string FullName
144+
{
145+
[DispId(289)]
146+
[LCIDConversion(0)]
147+
[return: MarshalAs(UnmanagedType.BStr)]
148+
get;
149+
}
150+
}
103151
}
104152
}

0 commit comments

Comments
 (0)