gpt4 book ai didi

interface - 起订量 : How to mock a class which is not visible?

转载 作者:行者123 更新时间:2023-12-02 23:51:05 26 4
gpt4 key购买 nike

我有以下简化代码来描述我的问题:

public interface IMyUser
{
int Id { get; set; }
string Name { get; set; }
}

它在数据访问层中使用如下:

public interface IData
{
T GetUserById<T>(int id) where T : IMyUser, new();
}

userlogic类定义如下:

public class UserLogic
{
private IData da;

public UserLogic(IData da)
{
this.da = da;
}

public IMyUser GetMyUserById(int id)
{
return da.GetUserById<MyUser>(id);
}
}

用户逻辑使用仅在内部可见的MyUSer类。

我想使用 Moq 来模拟对数据访问层的调用。但是因为我无法从我的单元测试代码(按设计)访问 MyUser 类,所以我不知道如何设置最小起订量?

起订量代码应该类似于:

var data = new Mock<IData>();
data.Setup(d => d.GetUserById<MyUser ???>(1)).Returns(???);

var logic = new UserLogic(data.Object);
var result = logic.GetMyUserById(1);

如何解决这个问题?

最佳答案

让我扩展一下 Sjoerd 的答案。您面临的问题是由于无法访问 MyUser从测试程序集中键入。这个问题很容易用 InternalsVisibleTo 解决。程序集属性。

但是,我建议重新考虑您的设计并摆脱 IMyUser接口(interface),而只需使用 MyUser类(应该是公共(public)的)。通常,您将服务放在接口(interface)后面,而不是实体后面。提供 IMyUser 的多个实现是否有任何充分的理由? ?

看看这个实现有多干净:

public interface IData
{
MyUser GetUserById(int id);
}

public class UserLogic
{
private IData da;

public UserLogic(IData da)
{
this.da = da;
}

public MyUser GetMyUserById(int id)
{
return da.GetUserById(id);
}
}

internal class MyUser {
int Id { get; set; }
string Name { get; set; }
}

如果您坚持使用IMyUser,还有另一种解决方案接口(interface)及其内部实现。你现有的解决方案,如果我推断 IData.GetUserById<T> 的内容正确的话,是这样的:

public class UserData : IData {
T GetUserById<T>(int id) where T : IMyUser, new(){
T returned = new T();
//fill in properties
returned.Name = "test";
return returned;
}
}

上面的代码稍微违反了SRP(warning, PDF)并混合了两个职责 - 从持久存储中检索实体并创建实体的实例。不仅如此,它还将创建责任放到了界面上,这就更糟糕了。

使用Abstract Factory解耦这些责任和 Dependency Injection(PDF)模式将带来更加简洁的设计,不会遇到与以前相同的问题。

public interface IMyUserFactory {
IMyUser Create();
}

public interface IData
{
IMyUser GetUserById(int id);
}

internal MyUserFactory : IMyUserFactory {
public IMyUser Create() {return new MyUser();}
}

internal class UserData : IData {

IMyUserFactory m_factory;
public UserData(IMyUserFactory factory) {
m_factory = factory;
}

public IMyUser GetUserById(int id) {
IMyUser returned = m_factory.Create();
//fill in properties
returned.Name = "test";
return returned;
}
}

//and finally UserLogic class
public class UserLogic
{
private IData da;

public UserLogic(IData da)
{
this.da = da;
}

public IMyUser GetMyUserById(int id)
{
return da.GetUserById(id);
}
}

//The test then becomes trivial
[TestMethod]
public void Test() {
var data = new Mock<IData>();
data.Setup(d => d.GetUserById(1)).Returns(new Mock<IMyUser>().Object);

var logic = new UserLogic(data.Object);
var result = logic.GetMyUserById(1);
}

关于interface - 起订量 : How to mock a class which is not visible?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3584305/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com