Skip to content

Commit

Permalink
Merge pull request #1076 from stakx/com-interop
Browse files Browse the repository at this point in the history
Make `Mock.Of<>` work with COM interop types that are annotated with `[CompilerGenerated]`
  • Loading branch information
stakx committed Oct 13, 2020
2 parents 5b8fbc4 + 1b0573e commit 7e2c0e8
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ The format is loosely based on [Keep a Changelog](http://keepachangelog.com/en/1
* Setup not triggered due to VB.NET transparently inserting superfluous type conversions into a setup expression (@InteXX, #1067)
* Nested mocks created by `Mock.Of<T>()` no longer have their properties stubbed since version 4.14.0 (@vruss, @1071)
* `Verify` fails for recursive setups not explicitly marked as `Verifiable` (@killergege, #1073)
* `Mock.Of<>` fails for COM interop types that are annotated with a `[CompilerGenerated]` custom attribute (@killergege, #1072)


## 4.14.6 (2020-09-30)
Expand Down
2 changes: 1 addition & 1 deletion src/Moq/Linq/MockSetupsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ private sealed class ReplaceMockObjectWithParameter : ExpressionVisitor

protected override Expression VisitMember(MemberExpression node)
{
if (node.Expression is ParameterExpression pe && pe.Type.IsDefined(typeof(CompilerGeneratedAttribute)))
if (node.Expression is ParameterExpression pe && pe.Type.IsDefined(typeof(CompilerGeneratedAttribute)) && pe.Type.Name.Contains("f__AnonymousType"))
{
// In LINQ query expressions with more than one `from` clause such as:
//
Expand Down
48 changes: 48 additions & 0 deletions tests/Moq.Tests/ComCompatibilityFixture.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Copyright (c) 2007, Clarius Consulting, Manas Technology Solutions, InSTEDD, and Contributors.
// All rights reserved. Licensed under the BSD 3-Clause License; see License.txt.

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

using Moq.Tests.ComTypes;

using Xunit;
Expand Down Expand Up @@ -100,5 +103,50 @@ public void COM_interop_type_indexer_setter_is_recognized_as_such()
var setter = indexer.GetSetMethod(true);
Assert.True(setter.IsSetAccessor() && setter.IsIndexerAccessor());
}

[Fact]
public void Can_create_mock_of_Excel_Workbook_using_Mock_Of_1()
{
_ = Mock.Of<GoodWorkbook>(workbook => workbook.FullName == "");
}

[Fact]
public void Can_create_mock_of_Excel_Workbook_using_Mock_Of_2()
{
_ = Mock.Of<BadWorkbook>(workbook => workbook.FullName == "");
}

// The following two interfaces are simplified versions of the `_Workbook` interface from
// two different versions of the `Microsoft.Office.Excel.Interop` interop assemblies.
// Note how they differ only in one `[CompilerGenerated]` attribute.

[ComImport]
[Guid("000208DA-0000-0000-C000-000000000046")]
public interface GoodWorkbook
{
[DispId(289)]
string FullName
{
[DispId(289)]
[LCIDConversion(0)]
[return: MarshalAs(UnmanagedType.BStr)]
get;
}
}

[ComImport]
[CompilerGenerated]
[Guid("000208DA-0000-0000-C000-000000000046")]
public interface BadWorkbook
{
[DispId(289)]
string FullName
{
[DispId(289)]
[LCIDConversion(0)]
[return: MarshalAs(UnmanagedType.BStr)]
get;
}
}
}
}

0 comments on commit 7e2c0e8

Please sign in to comment.