Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mocking PnPContext using Moq #948

Closed
jansenbe opened this issue Aug 22, 2022 Discussed in #789 · 14 comments
Closed

Mocking PnPContext using Moq #948

jansenbe opened this issue Aug 22, 2022 Discussed in #789 · 14 comments
Assignees
Labels
area: framework ⚙ Changes in the SDK core framework code

Comments

@jansenbe
Copy link
Contributor

Discussed in #789

Originally posted by sachinsatav March 14, 2022
Hi,
I am using PnP.Core in one of my project to create new sharepoint sites and I need to write unit tests around it.
I am able to mock context factory since there is an interface for it.
var _mockContextFactory = new Mock<IPnPContextFactory>();

However I am not able to mock PnPContext since there is no public constructor. Also there is not interface which I can use for mocking.

I looked at SDK test projects - https://github.com/pnp/pnpcore/tree/dev/src/sdk/PnP.Core.Test.Common & https://github.com/pnp/pnpcore/tree/dev/src/sdk/PnP.Core.Test but the setup is quite complicated and most of method calls used in there are only exposed to SDK solution projects.

Can someone please help with how I can mock PnPContext? Thank you.

@jansenbe
Copy link
Contributor Author

@sachinsatav, @wonderplayer : can you explain more about your requirements/needs. The mentioned discussion speaks about being able to set Web and Uri as properties...

@jansenbe jansenbe added the area: framework ⚙ Changes in the SDK core framework code label Aug 22, 2022
@wonderplayer
Copy link
Contributor

@jansenbe I'd like to set up unit testing. But if code contains PnP.Core framework in it, then I can't mock it - workaround to create class that will be calling PnP.Core and mock that class.
So, in general, it would be perfect if I could mock any part of PnPContext - web functions, administration, list, files, etc.

@jansenbe
Copy link
Contributor Author

@wonderplayer : can you show me a sample workaround class and sample test using that? Feel free to directly mail to bjansen@microsoft.com in case there's too much cleanup needed for public disclosure of the code.

@wonderplayer
Copy link
Contributor

@jansenbe Will this do?
https://github.com/wonderplayer/PnPCore-ConsoleApp

@jansenbe
Copy link
Contributor Author

@wonderplayer : I've just pushed this change (32dcbfb). Can you tomorrow evaluate and provide feedback. Let's work together to make PnP Core mockable using Moq.

@wonderplayer
Copy link
Contributor

@jansenbe Sure, let's do it 😊
Created mocked context, but tests failing. It requires ILogger - guess if I add resolution dependency injection for it, then it might work, but not necessarily all solutions will be using ILogger. At least IPnPContextFactory does not require ILogger dependency.

@jansenbe
Copy link
Contributor Author

@wonderplayer : can you share the stack trace of the failure?

@wonderplayer
Copy link
Contributor

@jansenbe I've pushed my changes to that repo.
New test file with mock PNP context.

@jansenbe
Copy link
Contributor Author

@wonderplayer : I did play a bit with your code and experimented with adding an interface for PnPContext. Using that below code works...would such an approach work for you?

var ctx = new Mock<IPnPContext> { DefaultValue = DefaultValue.Mock };

IWeb web = ctx.Object.Web;

ctx.Setup(c => c.Web.GetAsync()).ReturnsAsync(web);
var webMock = Mock.Get(web);
webMock.Setup(p => p.Title).Returns(title);

var result = await web.GetAsync();

Assert.AreEqual(title, result.Title);

Interface added on PnPContext:

/// <summary>
/// PnPContext interface to support mocking
/// </summary>
public interface IPnPContext
{
    /// <summary>
    /// Entry point for the Web Object
    /// </summary>
    IWeb Web { get; }
}

@jansenbe jansenbe self-assigned this Aug 23, 2022
@jansenbe
Copy link
Contributor Author

Code is not yet committed, will extend the interface to support additional objects before commit

@jansenbe
Copy link
Contributor Author

@wonderplayer : I pushed the interface change and dropped the static method. Let me know if this unblocks your scenario.

@wonderplayer
Copy link
Contributor

Thanks! I'll check tomorrow

@wonderplayer
Copy link
Contributor

@jansenbe with the scenario that I have, it works perfectly! Now I can mock various parts, as they are interfaces. Thank you!

@jansenbe
Copy link
Contributor Author

closing, thx!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: framework ⚙ Changes in the SDK core framework code
Projects
None yet
Development

No branches or pull requests

2 participants